diff --git a/.storybook/main.ts b/.storybook/main.ts
index 04248e5..c2a6558 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -28,6 +28,8 @@ const config: StorybookConfig = {
'@fast/mui-theme': path.resolve(currentDir, '../packages/mui-theme/src'),
'@fast/components': path.resolve(currentDir, '../packages/components/src'),
};
+ vite.optimizeDeps = vite.optimizeDeps || {};
+ vite.optimizeDeps.include = [...(vite.optimizeDeps?.include || []), 'aria-query', 'lz-string', '@testing-library/dom', '@testing-library/jest-dom'];
return vite;
},
};
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 8a868c6..0ed0083 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -33,6 +33,7 @@ const preview: Preview = {
{ value: 'fast_atlas', title: 'FAST Atlas' },
{ value: 'simplifica_core', title: 'Simplifica Core' },
{ value: 'simplifica_burlo', title: 'Simplifica Burlo' },
+ { value: 'smarttour', title: 'SmartTour' },
],
dynamicTitle: true,
},
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f782416..1729d3d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,38 @@
# @fast/graphics
+## 1.5.1
+
+Automated tests, custom calendar popup for FastDateInput, column-level filtering in FastTable with range support.
+
+### Storybook Tests
+- Currently supporting Interactions and Accessibility tests (Axe rules compliant).
+
+### FastDateInput
+
+- **Custom calendar popup**: replaced native ` ` with a full React-calendar. Month/year navigation with ChevronLeft/ChevronRight icons, 7-column day grid (Mon–Sun), selected day highlighted with brand `main` background + `contrastText`, today highlighted with `action.hover`.
+- **Today & Clear buttons**: popup footer with both actions. "Today" jumps to current date. "Clear" resets the value.
+- **Click-outside-to-close**: `useEffect` with `mousedown` listener on document closes the popup when clicking outside the wrapper.
+- **Focus state on Clear**: `setFocused(false)` forced in `commitDate` so the floating label drops back to center when clearing.
+- **`:active` moved to Trigger**: removed from the wrapper (which contained the popup), added to the Trigger div. Clicking calendar days, arrows, or buttons no longer triggers the press-down transform on the whole component.
+
+### FastTable
+
+- **New `columnFilterable` prop**: when true, renders a filter input row in `` below the header row. Each column gets a text input connected to `header.column.setFilterValue()`.
+- **Range filter support**: columns with `meta: { filterVariant: 'range' }` render two number inputs (Min / Max) instead of a single text input. Values are stored as `[min, max]` array.
+- **Built-in `inNumberRange`**: tanstack/react-table's native `inNumberRange` filter function. Uses `resolveFilterValue` for string-to-number parsing, auto-swaps min/max when inverted, and auto-removes when both inputs are empty.
+- **Age column filter**: data now use `filterFn: 'inNumberRange'` with `meta: { filterVariant: 'range' }`.
+
+### FastButton — aXe fixes
+
+- **`::before` moved to `StyledWrapper`**: pseudo-element moved from `.Btn` to the outer wrapper so `.Btn` has no overlapping pseudo-elements. aXe can now resolve color contrast against the single `background-color` on `.Btn`. Added `pointer-events: none` on `::before` to prevent click interception.
+- **Smooth default variant hover**: added `filter 0.2s ease` to `.Btn-content` transition. The default variant uses `filter: invert(1)` on hover which now fades smoothly instead of snapping, matching the fluid feel of outlined/text variants.
+
+### FastTextField / FastTextArea — aXe fixes
+
+- **`aria-label={placeholder}`**: added to both ` ` and `
{table.getRowModel().rows.map((row) => (
@@ -208,24 +260,6 @@ export function FastTable({
))}
- {showFooter && (
-
- {table.getFooterGroups().map((footerGroup) => (
-
- {footerGroup.headers.map((header) => (
-
- {header.isPlaceholder
- ? null
- : flexRender(
- header.column.columnDef.footer,
- header.getContext(),
- )}
-
- ))}
-
- ))}
-
- )}
);
@@ -314,6 +348,11 @@ const StyledWrapper = styled('div')<{
color: ${(p) => p.theme.palette.text.secondary};
border-top: 1px solid ${(p) => p.theme.palette.divider};
}
+
+ .filter-row th {
+ padding: 6px 8px;
+ vertical-align: top;
+ }
`;
const SortIndicator = styled('span')`
@@ -321,6 +360,65 @@ const SortIndicator = styled('span')`
margin-left: 4px;
`;
+const FilterInput = styled('input')`
+ width: 100%;
+ padding: 5px 6px;
+ border: 1px solid ${p => p.theme.palette.divider};
+ font-family: inherit;
+ font-size: 0.75rem;
+ color: ${p => p.theme.palette.text.primary};
+ background: ${p => p.theme.palette.background.paper};
+ outline: none;
+ box-sizing: border-box;
+
+ &:focus {
+ border-color: ${p => p.theme.palette.primary.main};
+ }
+
+ &::placeholder {
+ color: ${p => p.theme.palette.text.secondary};
+ }
+`;
+
+const RangeGroup = styled('div')`
+ display: flex;
+ align-items: center;
+ gap: 4px;
+`;
+
+const RangeSep = styled('span')`
+ color: ${p => p.theme.palette.text.secondary};
+ font-size: 0.75rem;
+ flex-shrink: 0;
+`;
+
+const RangeInput = styled('input')`
+ width: 100%;
+ padding: 5px 6px;
+ border: 1px solid ${p => p.theme.palette.divider};
+ font-family: inherit;
+ font-size: 0.75rem;
+ color: ${p => p.theme.palette.text.primary};
+ background: ${p => p.theme.palette.background.paper};
+ outline: none;
+ box-sizing: border-box;
+
+ &:focus {
+ border-color: ${p => p.theme.palette.primary.main};
+ }
+
+ &::placeholder {
+ color: ${p => p.theme.palette.text.secondary};
+ }
+
+ /* Hide native number spinners */
+ &::-webkit-inner-spin-button,
+ &::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+ }
+`;
+
const PaginationBar = styled('div')`
display: flex;
align-items: center;
diff --git a/packages/components/src/FastTextArea.tsx b/packages/components/src/FastTextArea.tsx
index a02102d..2f99fa7 100644
--- a/packages/components/src/FastTextArea.tsx
+++ b/packages/components/src/FastTextArea.tsx
@@ -93,6 +93,7 @@ export function FastTextArea({
onFocus={() => setFocused(true)}
onBlur={handleBlur}
disabled={disabled}
+ aria-label={placeholder || ''}
/>
{placeholder}
diff --git a/packages/components/src/FastTextField.tsx b/packages/components/src/FastTextField.tsx
index 709f3b0..36eb0d1 100644
--- a/packages/components/src/FastTextField.tsx
+++ b/packages/components/src/FastTextField.tsx
@@ -17,7 +17,7 @@ export interface FastTextFieldProps {
/** Floating label text. */
placeholder?: string;
/** Controlled value. */
- value?: string;
+ label?: string;
/** Uncontrolled initial value. */
defaultValue?: string;
/** Change handler. */
@@ -60,7 +60,7 @@ function clamp(num: number, min?: number, max?: number): number {
export function FastTextField({
color: accent = 'primary',
placeholder,
- value: controlledValue,
+ label: controlledValue,
defaultValue,
onChange,
disabled,
@@ -152,6 +152,7 @@ export function FastTextField({
onBlur={handleBlur}
disabled={disabled}
autoComplete="off"
+ aria-label={placeholder || ''}
/>
{placeholder}
diff --git a/packages/mui-theme/package.json b/packages/mui-theme/package.json
index d5b3a3a..ce48a4b 100644
--- a/packages/mui-theme/package.json
+++ b/packages/mui-theme/package.json
@@ -1,6 +1,6 @@
{
"name": "@fast/mui-theme",
- "version": "1.5.0",
+ "version": "1.5.1",
"private": false,
"description": "MUI theme creators derived from @fast/tokens",
"license": "MIT",
diff --git a/packages/tokens/dist/tokens.d.ts b/packages/tokens/dist/tokens.d.ts
index a8e2c8f..ea28267 100644
--- a/packages/tokens/dist/tokens.d.ts
+++ b/packages/tokens/dist/tokens.d.ts
@@ -1,4 +1,4 @@
-export type BrandName = 'fast_core' | 'fast_argos' | 'fast_atlas' | 'simplifica_core' | 'simplifica_burlo';
+export type BrandName = 'fast_core' | 'fast_argos' | 'fast_atlas' | 'simplifica_core' | 'simplifica_burlo' | 'smarttour';
export type BrandTokens = {
primary: {
main: string;
diff --git a/packages/tokens/dist/tokens.d.ts.map b/packages/tokens/dist/tokens.d.ts.map
index 82eda02..f84ac76 100644
--- a/packages/tokens/dist/tokens.d.ts.map
+++ b/packages/tokens/dist/tokens.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAEvF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAA;IACD,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAA;IACD,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAA;CACF,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CA+HtD,CAAC"}
\ No newline at end of file
+{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,WAAW,CAAC;AAErG,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAA;IACD,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAA;IACD,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAA;CACF,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAsJtD,CAAC"}
\ No newline at end of file
diff --git a/packages/tokens/dist/tokens.js b/packages/tokens/dist/tokens.js
index da208bd..56fb04f 100644
--- a/packages/tokens/dist/tokens.js
+++ b/packages/tokens/dist/tokens.js
@@ -101,13 +101,13 @@ export const brandTokens = {
},
simplifica_burlo: {
primary: {
- main: '#1B9A75',
- dark: '#0F6E56',
+ main: '#0F6E56', // old: #1B9A75
+ dark: '#094637',
light: '#84c8bb',
},
secondary: {
- main: '#FABA59',
- dark: '#E09A30',
+ main: '#FABA59', // old: #FABA59
+ dark: '#a77e3d',
light: '#ffd9a0',
},
background: {
@@ -123,5 +123,29 @@ export const brandTokens = {
mono: '"Roboto Mono", monospace',
}
},
+ smarttour: {
+ primary: {
+ main: '#3B4CCA',
+ dark: '#232D7A',
+ light: '#8C98EC',
+ },
+ secondary: {
+ main: '#FF6B57',
+ dark: '#B84030',
+ light: '#FFA396',
+ },
+ background: {
+ default: '#F5F6FA',
+ paper: '#FFFFFF',
+ },
+ text: {
+ primary: '#12131A',
+ secondary: '#5A5E73',
+ },
+ font: {
+ main: '"Google Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
+ mono: '"Roboto Mono", monospace',
+ }
+ }
};
//# sourceMappingURL=tokens.js.map
\ No newline at end of file
diff --git a/packages/tokens/dist/tokens.js.map b/packages/tokens/dist/tokens.js.map
index d567411..abfca13 100644
--- a/packages/tokens/dist/tokens.js.map
+++ b/packages/tokens/dist/tokens.js.map
@@ -1 +1 @@
-{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAmC;IACzD,SAAS,EAAE;QACT,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;SACjB;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,SAAS;SACrB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,kFAAkF;YACxF,IAAI,EAAE,0BAA0B;SACjC;KACF;IAED,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;SACjB;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,SAAS;SACrB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,kFAAkF;YACxF,IAAI,EAAE,0BAA0B;SACjC;KACF;IAED,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;SACjB;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,SAAS;SACrB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,kFAAkF;YACxF,IAAI,EAAE,0BAA0B;SACjC;KACF;IAED,eAAe,EAAE;QACf,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;SACjB;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,SAAS;SACrB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,kFAAkF;YACxF,IAAI,EAAE,0BAA0B;SACjC;KACF;IAED,gBAAgB,EAAE;QAChB,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACjB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;SACjB;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,SAAS;SACrB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,kFAAkF;YACxF,IAAI,EAAE,0BAA0B;SACjC;KACF;CAGF,CAAC"}
\ No newline at end of file
+{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/tokens/package.json b/packages/tokens/package.json
index 213fcc0..91d1089 100644
--- a/packages/tokens/package.json
+++ b/packages/tokens/package.json
@@ -1,6 +1,6 @@
{
"name": "@fast/tokens",
- "version": "1.5.0",
+ "version": "1.5.1",
"private": false,
"description": "FAST design tokens",
"license": "MIT",
diff --git a/packages/tokens/src/tokens.ts b/packages/tokens/src/tokens.ts
index 18275fd..c54febd 100644
--- a/packages/tokens/src/tokens.ts
+++ b/packages/tokens/src/tokens.ts
@@ -1,5 +1,5 @@
export type BrandName =
- 'fast_core' | 'fast_argos' | 'fast_atlas' | 'simplifica_core' | 'simplifica_burlo';
+ 'fast_core' | 'fast_argos' | 'fast_atlas' | 'simplifica_core' | 'simplifica_burlo' | 'smarttour';
export type BrandTokens = {
primary: {
@@ -133,13 +133,13 @@ export const brandTokens: Record = {
simplifica_burlo: {
primary: {
- main: '#1B9A75',
- dark: '#0F6E56',
+ main: '#0F6E56', // old: #1B9A75
+ dark: '#094637',
light: '#84c8bb',
},
secondary: {
- main: '#FABA59',
- dark: '#E09A30',
+ main: '#FABA59', // old: #FABA59
+ dark: '#a77e3d',
light: '#ffd9a0',
},
background: {
@@ -156,5 +156,28 @@ export const brandTokens: Record = {
}
},
-
+ smarttour: {
+ primary: {
+ main: '#3B4CCA',
+ dark: '#232D7A',
+ light: '#8C98EC',
+ },
+ secondary: {
+ main: '#FF6B57',
+ dark: '#B84030',
+ light: '#FFA396',
+ },
+ background: {
+ default: '#F5F6FA',
+ paper: '#FFFFFF',
+ },
+ text: {
+ primary: '#12131A',
+ secondary: '#5A5E73',
+ },
+ font: {
+ main: '"Google Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
+ mono: '"Roboto Mono", monospace',
+ }
+}
};
diff --git a/playground/package.json b/playground/package.json
index 180b94b..b3371df 100644
--- a/playground/package.json
+++ b/playground/package.json
@@ -1,6 +1,6 @@
{
"name": "@fast/playground",
- "version": "1.5.0",
+ "version": "1.5.1",
"private": true,
"type": "module",
"scripts": {
diff --git a/playground/src/App.tsx b/playground/src/App.tsx
index aeacd47..ee395e2 100644
--- a/playground/src/App.tsx
+++ b/playground/src/App.tsx
@@ -230,6 +230,7 @@ export default function App() {
sortable
pageable
searchable
+ filterable
renderActions={(row) => (
} color="primary" variant="text" width="50%" height={26} fontSize={10} onClick={() => alert(`Petted ${row.name}!`)} />
diff --git a/playground/src/data/tableData.tsx b/playground/src/data/tableData.tsx
index 263c28f..fa48934 100644
--- a/playground/src/data/tableData.tsx
+++ b/playground/src/data/tableData.tsx
@@ -127,6 +127,7 @@ export const defaultColumns: ColumnDef[] = [
}),
columnHelper.accessor('age', {
header: 'Age (Years)',
+ filterFn: 'includesString',
cell: (info) => info.renderValue(),
footer: (info) => info.column.id,
}),
@@ -140,6 +141,8 @@ export const defaultColumns: ColumnDef[] = [
}),
columnHelper.accessor('zoomiesProgress', {
header: 'Zoomies Progress (%)',
+ filterFn: 'includesString',
+ cell: (info) => info.renderValue(),
footer: (info) => info.column.id,
}),
];
\ No newline at end of file
diff --git a/stories/FastBurger.stories.tsx b/stories/FastBurger.stories.tsx
deleted file mode 100644
index d585777..0000000
--- a/stories/FastBurger.stories.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import { FastBurger } from '../packages/components/src/FastBurger';
-
-const meta: Meta = {
- title: 'Navigation/FastBurger',
- component: FastBurger,
- tags: ['autodocs'],
- argTypes: {
- color: { control: 'radio', options: ['primary', 'secondary'] },
- size: { control: 'number' },
- defaultChecked: { control: 'boolean' },
- },
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {};
-
-export const Checked: Story = {
- args: { defaultChecked: true },
-};
-
-export const Secondary: Story = {
- args: { color: 'secondary' },
-};
diff --git a/stories/FastButton.stories.tsx b/stories/FastButton.stories.tsx
index bde2c5d..b70cc34 100644
--- a/stories/FastButton.stories.tsx
+++ b/stories/FastButton.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastButton } from '../packages/components/src/FastButton';
import PaymentIcon from '@mui/icons-material/Payment';
@@ -48,7 +49,31 @@ export default meta;
type Story = StoryObj;
export const Default: Story = {
- args: { label: 'Button', color: 'primary', variant: 'default', width: '130px', height: '40px', animated: true },
+ args: { label: 'Button', color: 'primary', variant: 'default', width: '130px', height: '40px', animated: false },
+};
+
+export const Animated: Story = {
+ args: { ...Default.args, animated: true },
+};
+
+export const PrimaryLight: Story = {
+ args: { ...Default.args, color: 'primaryLight' },
+};
+
+export const PrimaryDark: Story = {
+ args: { ...Default.args, color: 'primaryDark' },
+};
+
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
+export const SecondaryLight: Story = {
+ args: { ...Default.args, color: 'secondaryLight' },
+};
+
+export const SecondaryDark: Story = {
+ args: { ...Default.args, color: 'secondaryDark' },
};
export const Outlined: Story = {
diff --git a/stories/FastCard.stories.tsx b/stories/FastCard.stories.tsx
index c83aba8..bce913f 100644
--- a/stories/FastCard.stories.tsx
+++ b/stories/FastCard.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastCard } from '../packages/components/src/FastCard';
import { FastButton } from '../packages/components/src/FastButton';
diff --git a/stories/FastCardFA.stories.tsx b/stories/FastCardFA.stories.tsx
index 4245364..cb293cb 100644
--- a/stories/FastCardFA.stories.tsx
+++ b/stories/FastCardFA.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastCardFA } from '../packages/components/src/FastCardFA';
import { FastButton } from '../packages/components/src/FastButton';
diff --git a/stories/FastCheckbox.stories.tsx b/stories/FastCheckbox.stories.tsx
index d278014..85d2b53 100644
--- a/stories/FastCheckbox.stories.tsx
+++ b/stories/FastCheckbox.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastCheckbox } from '../packages/components/src/FastCheckbox';
@@ -22,6 +23,10 @@ export const Default: Story = {
args: { label: 'Accept terms' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const Checked: Story = {
args: { ...Default.args, defaultChecked: true },
};
diff --git a/stories/FastDateInput.stories.tsx b/stories/FastDateInput.stories.tsx
index 58d4359..a53e067 100644
--- a/stories/FastDateInput.stories.tsx
+++ b/stories/FastDateInput.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastDateInput } from '../packages/components/src/FastDateInput';
@@ -22,6 +23,10 @@ export const Default: Story = {
args: { placeholder: 'Select date', width: '240px' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const WithValue: Story = {
args: { ...Default.args, defaultValue: '2026-07-15' },
};
diff --git a/stories/FastDialog.stories.tsx b/stories/FastDialog.stories.tsx
index 75c0ebe..bceef4c 100644
--- a/stories/FastDialog.stories.tsx
+++ b/stories/FastDialog.stories.tsx
@@ -1,8 +1,9 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { useState } from 'react';
import { FastDialog } from '../packages/components/src/FastDialog';
import { FastButton } from '../packages/components/src/FastButton';
-import { Button, Typography, Box } from '@mui/material';
+import { Typography, Box } from '@mui/material';
const meta: Meta = {
title: 'Feedback/FastDialog',
@@ -40,3 +41,4 @@ export const Default: Story = {
},
};
+
diff --git a/stories/FastDropdown.stories.tsx b/stories/FastDropdown.stories.tsx
index b445002..d5b7055 100644
--- a/stories/FastDropdown.stories.tsx
+++ b/stories/FastDropdown.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastDropdown } from '../packages/components/src/FastDropdown';
@@ -27,6 +28,11 @@ export const Default: Story = {
),
};
+export const Secondary: Story = {
+ ...Default,
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const Outlined: Story = {
...Default,
args: { ...Default.args, variant: 'outlined' },
diff --git a/stories/FastEmptyState.stories.tsx b/stories/FastEmptyState.stories.tsx
index 6af2819..5288634 100644
--- a/stories/FastEmptyState.stories.tsx
+++ b/stories/FastEmptyState.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastEmptyState } from '../packages/components/src/FastEmptyState';
import { FastButton } from '../packages/components/src/FastButton';
diff --git a/stories/FastLoader.stories.tsx b/stories/FastLoader.stories.tsx
index 013b4f9..06b4dfe 100644
--- a/stories/FastLoader.stories.tsx
+++ b/stories/FastLoader.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastLoader } from '../packages/components/src/FastLoader';
diff --git a/stories/FastRadio.stories.tsx b/stories/FastRadio.stories.tsx
index a30f4ad..93ebc60 100644
--- a/stories/FastRadio.stories.tsx
+++ b/stories/FastRadio.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastRadio } from '../packages/components/src/FastRadio';
import { Box } from '@mui/material';
@@ -22,6 +23,10 @@ export const Default: Story = {
args: { label: 'Option A', name: 'group' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const RadioGroup: Story = {
render: () => (
diff --git a/stories/FastRadioBox.stories.tsx b/stories/FastRadioBox.stories.tsx
index 784e17f..f4e545e 100644
--- a/stories/FastRadioBox.stories.tsx
+++ b/stories/FastRadioBox.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastRadioBox } from '../packages/components/src/FastRadioBox';
import PetsIcon from '@mui/icons-material/Pets';
@@ -26,6 +27,10 @@ export const Default: Story = {
args: { icon: , label: 'Cat', name: 'pet', width: 80, height: 80 },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const FoodGroup: Story = {
args: {
color: "primary"
diff --git a/stories/FastSlider.stories.tsx b/stories/FastSlider.stories.tsx
index bed9ab5..111597b 100644
--- a/stories/FastSlider.stories.tsx
+++ b/stories/FastSlider.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastSlider } from '../packages/components/src/FastSlider';
import { Box } from '@mui/material';
@@ -27,6 +28,10 @@ export const Default: Story = {
args: { defaultValue: 50, width: '300px' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const WithLabel: Story = {
args: { ...Default.args, label: 'Volume' },
};
diff --git a/stories/FastSnackbar.stories.tsx b/stories/FastSnackbar.stories.tsx
index 593544c..02ae15e 100644
--- a/stories/FastSnackbar.stories.tsx
+++ b/stories/FastSnackbar.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { useState } from 'react';
import { FastSnackbar } from '../packages/components/src/FastSnackbar';
diff --git a/stories/FastTable.stories.tsx b/stories/FastTable.stories.tsx
index 8e92c0e..eefe331 100644
--- a/stories/FastTable.stories.tsx
+++ b/stories/FastTable.stories.tsx
@@ -1,40 +1,53 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastTable } from '../packages/components/src/FastTable';
import { createColumnHelper, type ColumnDef } from '@tanstack/react-table';
-type Person = { name: string; age: number; email: string };
+type Person = { name: string; age: number; email: string; delivered: string };
const data: Person[] = [
- { name: 'Alice', age: 30, email: 'alice@example.com' },
- { name: 'Bob', age: 25, email: 'bob@example.com' },
- { name: 'Charlie', age: 35, email: 'charlie@example.com' },
- { name: 'Diana', age: 28, email: 'diana@example.com' },
- { name: 'Ethan', age: 32, email: 'ethan@example.com' },
- { name: 'Fiona', age: 27, email: 'fiona@example.com' },
- { name: 'George', age: 41, email: 'george@example.com' },
- { name: 'Hannah', age: 29, email: 'hannah@example.com' },
- { name: 'Ian', age: 34, email: 'ian@example.com' },
- { name: 'Julia', age: 31, email: 'julia@example.com' },
- { name: 'Kevin', age: 26, email: 'kevin@example.com' },
- { name: 'Laura', age: 33, email: 'laura@example.com' },
- { name: 'Marcus', age: 38, email: 'marcus@example.com' },
- { name: 'Natalie', age: 24, email: 'natalie@example.com' },
- { name: 'Oliver', age: 45, email: 'oliver@example.com' },
- { name: 'Penelope', age: 29, email: 'penelope@example.com' },
- { name: 'Quentin', age: 36, email: 'quentin@example.com' },
- { name: 'Rachel', age: 30, email: 'rachel@example.com' },
- { name: 'Samuel', age: 27, email: 'samuel@example.com' },
- { name: 'Tina', age: 42, email: 'tina@example.com' },
- { name: 'Victor', age: 31, email: 'victor@example.com' },
- { name: 'Wendy', age: 25, email: 'wendy@example.com' },
- { name: 'Xavier', age: 39, email: 'xavier@example.com' },
- { name: 'Yasmin', age: 28, email: 'yasmin@example.com' },
- { name: 'Zachary', age: 33, email: 'zachary@example.com' }
+ { name: 'Alice', age: 30, email: 'alice@example.com', delivered: 'yes' },
+ { name: 'Bob', age: 25, email: 'bob@example.com', delivered: 'no' },
+ { name: 'Charlie', age: 35, email: 'charlie@example.com', delivered: 'yes' },
+ { name: 'Diana', age: 28, email: 'diana@example.com', delivered: 'yes' },
+ { name: 'Ethan', age: 32, email: 'ethan@example.com', delivered: 'no' },
+ { name: 'Fiona', age: 27, email: 'fiona@example.com', delivered: 'yes' },
+ { name: 'George', age: 41, email: 'george@example.com', delivered: 'no' },
+ { name: 'Hannah', age: 29, email: 'hannah@example.com', delivered: 'yes' },
+ { name: 'Ian', age: 34, email: 'ian@example.com', delivered: 'no' },
+ { name: 'Julia', age: 31, email: 'julia@example.com', delivered: 'yes' },
+ { name: 'Kevin', age: 26, email: 'kevin@example.com', delivered: 'no' },
+ { name: 'Laura', age: 33, email: 'laura@example.com', delivered: 'yes' },
+ { name: 'Marcus', age: 38, email: 'marcus@example.com', delivered: 'yes' },
+ { name: 'Natalie', age: 24, email: 'natalie@example.com', delivered: 'no' },
+ { name: 'Oliver', age: 45, email: 'oliver@example.com', delivered: 'yes' },
+ { name: 'Penelope', age: 29, email: 'penelope@example.com', delivered: 'no' },
+ { name: 'Quentin', age: 36, email: 'quentin@example.com', delivered: 'yes' },
+ { name: 'Rachel', age: 30, email: 'rachel@example.com', delivered: 'yes' },
+ { name: 'Samuel', age: 27, email: 'samuel@example.com', delivered: 'no' },
+ { name: 'Tina', age: 42, email: 'tina@example.com', delivered: 'yes' },
+ { name: 'Victor', age: 31, email: 'victor@example.com', delivered: 'no' },
+ { name: 'Wendy', age: 25, email: 'wendy@example.com', delivered: 'yes' },
+ { name: 'Xavier', age: 39, email: 'xavier@example.com', delivered: 'no' },
+ { name: 'Yasmin', age: 28, email: 'yasmin@example.com', delivered: 'yes' },
+ { name: 'Zachary', age: 33, email: 'zachary@example.com', delivered: 'no' },
];
const ch = createColumnHelper();
const columns: ColumnDef[] = [
- ch.accessor('name', { header: 'Name', cell: info => info.getValue() }),
- ch.accessor('age', { header: 'Age', cell: info => info.getValue() }),
- ch.accessor('email', { header: 'Email', cell: info => info.getValue() }),
+ ch.accessor('name', {
+ header: 'Name',
+ cell: info => info.getValue() }),
+ ch.accessor('age', {
+ header: 'Age',
+ filterFn: 'inNumberRange', //
+ meta: { filterVariant: 'range' }, // Optional values that sets a range instead of a single filter
+ cell: info => info.getValue() }),
+ ch.accessor('email', {
+ header: 'Email',
+ cell: info => info.getValue() }),
+ ch.accessor('delivered', {
+ header: 'Delivered',
+ cell: info => info.getValue() === 'yes' ? '✅' : '❌',
+ }),
];
const meta: Meta = {
@@ -46,9 +59,9 @@ const meta: Meta = {
sortable: { control: 'boolean' },
pageable: { control: 'boolean' },
searchable: { control: 'boolean' },
+ filterable: { control: 'boolean' },
striped: { control: 'boolean' },
hoverable: { control: 'boolean' },
- showFooter: { control: 'boolean' },
width: { control: 'text' },
},
};
@@ -60,6 +73,10 @@ export const Default: Story = {
args: { data, columns, width: '100%' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const Sortable: Story = {
args: { ...Default.args, sortable: true },
};
@@ -71,3 +88,7 @@ export const Pageable: Story = {
export const Searchable: Story = {
args: { ...Pageable.args, searchable: true },
};
+
+export const filterable: Story = {
+ args: { ...Pageable.args, filterable: true },
+};
diff --git a/stories/FastTextArea.stories.tsx b/stories/FastTextArea.stories.tsx
index 5c4b965..668b7cb 100644
--- a/stories/FastTextArea.stories.tsx
+++ b/stories/FastTextArea.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastTextArea } from '../packages/components/src/FastTextArea';
@@ -27,6 +28,10 @@ export const Default: Story = {
args: { placeholder: 'Tell us about your cat', width: '360px', rows: 4 },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const WithValue: Story = {
args: { ...Default.args, defaultValue: 'Whiskers is a 3-year-old tabby who loves naps and salmon.' },
};
diff --git a/stories/FastTextField.stories.tsx b/stories/FastTextField.stories.tsx
index 2cc981b..0e47875 100644
--- a/stories/FastTextField.stories.tsx
+++ b/stories/FastTextField.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastTextField } from '../packages/components/src/FastTextField';
import { Box } from '@mui/material';
@@ -32,6 +33,10 @@ export const Default: Story = {
args: { placeholder: 'Enter text', width: '300px' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const WithError: Story = {
args: { ...Default.args, errorMessage: 'This field is invalid' },
};
diff --git a/stories/FastThemeProvider.stories.tsx b/stories/FastThemeProvider.stories.tsx
index 9d26e25..08383e6 100644
--- a/stories/FastThemeProvider.stories.tsx
+++ b/stories/FastThemeProvider.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastThemeProvider } from '../packages/components/src/FastThemeProvider';
import { useTheme } from '@mui/material/styles';
@@ -49,7 +50,7 @@ const meta: Meta = {
argTypes: {
brand: {
control: 'select',
- options: ['fast_core', 'fast_argos', 'fast_atlas', 'simplifica_core', 'simplifica_burlo'],
+ options: ['fast_core', 'fast_argos', 'fast_atlas', 'simplifica_core', 'simplifica_burlo', 'smarttour'],
},
withCssBaseline: { control: 'boolean' },
withComponentDefaults: { control: 'boolean' },
diff --git a/stories/FastToggle.stories.tsx b/stories/FastToggle.stories.tsx
index 11dcce9..e975909 100644
--- a/stories/FastToggle.stories.tsx
+++ b/stories/FastToggle.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastToggle } from '../packages/components/src/FastToggle';
@@ -20,6 +21,10 @@ export const Default: Story = {
args: { label: 'Enable notifications' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const Checked: Story = {
args: { ...Default.args, defaultChecked: true },
};
diff --git a/stories/FastTooltip.stories.tsx b/stories/FastTooltip.stories.tsx
index c0fadf0..46bd5d0 100644
--- a/stories/FastTooltip.stories.tsx
+++ b/stories/FastTooltip.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastTooltip } from '../packages/components/src/FastTooltip';
import { FastButton } from '../packages/components/src/FastButton';
diff --git a/stories/FastUpload.stories.tsx b/stories/FastUpload.stories.tsx
index a7ffaad..3e435dc 100644
--- a/stories/FastUpload.stories.tsx
+++ b/stories/FastUpload.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { FastUpload } from '../packages/components/src/FastUpload';
@@ -27,6 +28,10 @@ export const Default: Story = {
args: { label: 'Click to upload', width: '300px' },
};
+export const Secondary: Story = {
+ args: { ...Default.args, color: 'secondary' },
+};
+
export const ImagesOnly: Story = {
args: { ...Default.args, label: 'Upload cat photo', accept: 'image/*' },
};