@spaced-out/genesis-mcp 1.0.18 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/design-system.json +68 -20
- package/package.json +1 -1
package/data/design-system.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"metadata": {
|
|
3
|
-
"buildDate": "2026-
|
|
4
|
-
"version": "0.6.
|
|
3
|
+
"buildDate": "2026-05-25T08:18:26.307Z",
|
|
4
|
+
"version": "0.6.19",
|
|
5
5
|
"designSystemPath": "/home/runner/work/ui-design-system/ui-design-system"
|
|
6
6
|
},
|
|
7
7
|
"components": {
|
|
@@ -409,7 +409,7 @@
|
|
|
409
409
|
"css": null,
|
|
410
410
|
"index": {
|
|
411
411
|
"path": "index.d.ts",
|
|
412
|
-
"content": "export * from '../../components/Charts/ChartTooltip';\nexport * from '../../components/Charts/ChartWrapper';\nexport * from '../../components/Charts/ColumnChart';\nexport * from '../../components/Charts/DonutChart';\nexport * from '../../components/Charts/FunnelChart';\nexport * from '../../components/Charts/LineChart';\nexport * from '../../components/Charts/SankeyChart';\nexport * from '../../components/Charts/SpiderChart';\nexport * from '../../components/Charts/StackedBarChart';\n//# sourceMappingURL=index.d.ts.map"
|
|
412
|
+
"content": "export * from '../../components/Charts/ChartTooltip';\nexport * from '../../components/Charts/ChartWrapper';\nexport * from '../../components/Charts/ColumnChart';\nexport * from '../../components/Charts/DonutChart';\nexport * from '../../components/Charts/FunnelChart';\nexport * from '../../components/Charts/LineChart';\nexport * from '../../components/Charts/SankeyChart';\nexport * from '../../components/Charts/SpiderChart';\nexport * from '../../components/Charts/StackedBarChart';\nexport * from '../../components/Charts/UniversalChart';\n//# sourceMappingURL=index.d.ts.map"
|
|
413
413
|
},
|
|
414
414
|
"additional": {
|
|
415
415
|
"ChartTooltip/index.d.ts": {
|
|
@@ -479,6 +479,18 @@
|
|
|
479
479
|
"StackedBarChart/index.d.ts": {
|
|
480
480
|
"path": "StackedBarChart/index.d.ts",
|
|
481
481
|
"content": "export * from '../../../components/Charts/StackedBarChart/StackedBarChart';\n//# sourceMappingURL=index.d.ts.map"
|
|
482
|
+
},
|
|
483
|
+
"UniversalChart/UniversalChart.d.ts": {
|
|
484
|
+
"path": "UniversalChart/UniversalChart.d.ts",
|
|
485
|
+
"content": "import * as React from 'react';\nimport type { CategoricalChartKind, ChartKindOptionType, FlowChartKind, ProportionChartKind, UniversalChartProps } from '../../../components/Charts/UniversalChart/UniversalChart.types';\nexport declare const CHART_KIND_OPTIONS: Readonly<{\n column: ChartKindOptionType<\"column\">;\n line: ChartKindOptionType<\"line\">;\n donut: ChartKindOptionType<\"donut\">;\n funnel: ChartKindOptionType<\"funnel\">;\n sankey: ChartKindOptionType<\"sankey\">;\n spider: ChartKindOptionType<\"spider\">;\n stackedBar: ChartKindOptionType<\"stackedBar\">;\n}>;\nexport declare const CHART_KIND_GROUPS: Readonly<{\n CATEGORICAL: Array<ChartKindOptionType<CategoricalChartKind>>;\n PROPORTION: Array<ChartKindOptionType<ProportionChartKind>>;\n FLOW: Array<ChartKindOptionType<FlowChartKind>>;\n}>;\nexport type { UniversalChartProps, ChartKind, ChartKindOptionType, ChartKindSelectorProps, CategoricalChartKind, ProportionChartKind, FlowChartKind, } from '../../../components/Charts/UniversalChart/UniversalChart.types';\nexport declare const UniversalChart: {\n (props: UniversalChartProps): React.JSX.Element;\n displayName: string;\n};\n//# sourceMappingURL=UniversalChart.d.ts.map"
|
|
486
|
+
},
|
|
487
|
+
"UniversalChart/UniversalChart.types.d.ts": {
|
|
488
|
+
"path": "UniversalChart/UniversalChart.types.d.ts",
|
|
489
|
+
"content": "import type { ColumnChartProps } from '../../../components/Charts/ColumnChart';\nimport type { DonutChartProps } from '../../../components/Charts/DonutChart';\nimport type { FunnelChartProps } from '../../../components/Charts/FunnelChart';\nimport type { LineChartProps } from '../../../components/Charts/LineChart';\nimport type { SankeyChartProps } from '../../../components/Charts/SankeyChart';\nimport type { SpiderChartProps } from '../../../components/Charts/SpiderChart';\nimport type { StackedBarChartProps } from '../../../components/Charts/StackedBarChart';\nexport type ChartKind = 'column' | 'line' | 'donut' | 'funnel' | 'sankey' | 'spider' | 'stackedBar';\nexport type CategoricalChartKind = 'column' | 'line' | 'stackedBar' | 'spider';\nexport type ProportionChartKind = 'donut' | 'funnel';\nexport type FlowChartKind = 'sankey';\nexport interface ChartKindOptionType<K extends ChartKind = ChartKind> {\n key: K;\n label: string;\n}\nexport interface ChartKindSelectorProps {\n showChartKindSwitcher?: boolean;\n chartKindOptions?: Array<ChartKindOptionType<CategoricalChartKind>> | Array<ChartKindOptionType<ProportionChartKind>> | Array<ChartKindOptionType<FlowChartKind>>;\n onChartKindChange?: (chartKind: ChartKind) => void;\n responsive?: boolean;\n}\nexport type UniversalChartProps = (({\n chartKind: 'column';\n} & ColumnChartProps) | ({\n chartKind: 'line';\n} & LineChartProps) | ({\n chartKind: 'donut';\n} & DonutChartProps) | ({\n chartKind: 'funnel';\n} & FunnelChartProps) | ({\n chartKind: 'sankey';\n} & SankeyChartProps) | ({\n chartKind: 'spider';\n} & SpiderChartProps) | ({\n chartKind: 'stackedBar';\n} & StackedBarChartProps)) & ChartKindSelectorProps;\n//# sourceMappingURL=UniversalChart.types.d.ts.map"
|
|
490
|
+
},
|
|
491
|
+
"UniversalChart/index.d.ts": {
|
|
492
|
+
"path": "UniversalChart/index.d.ts",
|
|
493
|
+
"content": "export * from '../../../components/Charts/UniversalChart/UniversalChart';\n//# sourceMappingURL=index.d.ts.map"
|
|
482
494
|
}
|
|
483
495
|
}
|
|
484
496
|
},
|
|
@@ -523,6 +535,12 @@
|
|
|
523
535
|
"StackedBarChart/StackedBarChart.stories.tsx",
|
|
524
536
|
"StackedBarChart/StackedBarChart.tsx",
|
|
525
537
|
"StackedBarChart/index.ts",
|
|
538
|
+
"UniversalChart/UniversalChart.module.css",
|
|
539
|
+
"UniversalChart/UniversalChart.stories.module.css",
|
|
540
|
+
"UniversalChart/UniversalChart.stories.tsx",
|
|
541
|
+
"UniversalChart/UniversalChart.tsx",
|
|
542
|
+
"UniversalChart/UniversalChart.types.ts",
|
|
543
|
+
"UniversalChart/index.ts",
|
|
526
544
|
"index.ts"
|
|
527
545
|
]
|
|
528
546
|
},
|
|
@@ -886,6 +904,36 @@
|
|
|
886
904
|
"index.ts"
|
|
887
905
|
]
|
|
888
906
|
},
|
|
907
|
+
"DraggableWrapper": {
|
|
908
|
+
"name": "DraggableWrapper",
|
|
909
|
+
"path": "src/components/DraggableWrapper",
|
|
910
|
+
"files": {
|
|
911
|
+
"main": {
|
|
912
|
+
"path": "DraggableWrapper.d.ts",
|
|
913
|
+
"content": "import * as React from 'react';\nexport type DraggableWrapperClassNames = Readonly<{\n /** Override or extend the root wrapper element. */\n wrapper?: string;\n /** Override or extend the drag handle element. */\n dragHandle?: string;\n}>;\nexport interface DraggableWrapperProps extends Pick<React.HTMLAttributes<HTMLDivElement>, 'onDragStart' | 'onDragEnd' | 'onDragOver' | 'onDrop'> {\n children: React.ReactNode;\n /** Applies the dragging visual state (purple outline + reduced opacity). */\n isDragging?: boolean;\n /** Label for the drag handle (tooltip and aria-label). Pass a translated string for i18n. */\n dragHandleLabel?: string;\n /** Class names to override or extend internal elements (e.g. from parent CSS modules). */\n classNames?: DraggableWrapperClassNames;\n /**\n * Called when the user presses ArrowUp/ArrowLeft or ArrowDown/ArrowRight while\n * the item is keyboard-grabbed. Use this to reorder the list in state.\n */\n onKeyboardReorder?: (direction: 'up' | 'down') => void;\n testId?: string;\n /** Set false when using @dnd-kit / react-beautiful-dnd (pointer-event libs). Keep true for react-dnd HTML5 backend. Default true. */\n enableNativeDrag?: boolean;\n /** Extra props to spread on the wrapper (library listeners/attributes). */\n wrapperProps?: React.HTMLAttributes<HTMLDivElement>;\n /** Extra props to spread on the drag handle (some libs attach activator listeners here). */\n dragHandleProps?: React.HTMLAttributes<HTMLDivElement>;\n /** Separate ref for the drag handle (for libs with setActivatorNodeRef / react-dnd's drag). */\n dragHandleRef?: React.Ref<HTMLDivElement>;\n}\nexport declare const DraggableWrapper: React.ForwardRefExoticComponent<DraggableWrapperProps & React.RefAttributes<HTMLDivElement>>;\n//# sourceMappingURL=DraggableWrapper.d.ts.map"
|
|
914
|
+
},
|
|
915
|
+
"story": {
|
|
916
|
+
"path": "DraggableWrapper.stories.tsx",
|
|
917
|
+
"content": "import * as React from 'react';\n\nimport {TEXT_COLORS} from 'src/types/typography';\nimport classify from 'src/utils/classify';\n\nimport {ColumnChart} from 'src/components/Charts/ColumnChart';\nimport {DraggableWrapper} from 'src/components/DraggableWrapper';\nimport {Icon} from 'src/components/Icon';\nimport {KPIBox} from 'src/components/KPIBox';\nimport {BasicSingleCell, type GenericObject, Table} from 'src/components/Table';\nimport {BodyMediumBold, BodySmall} from 'src/components/Text';\n\nimport css from 'src/components/DraggableWrapper/DraggableWrapper.stories.module.css';\n\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/DraggableWrapper',\n component: DraggableWrapper,\n argTypes: {\n children: {\n description: 'The component to wrap with drag-to-reorder behavior.',\n control: {type: 'object'},\n table: {\n type: {summary: 'React.ReactNode'},\n },\n },\n isDragging: {\n description:\n 'Applies the dragging visual state (50% opacity + purple ring) to the placeholder left in place while dragging.',\n control: {type: 'boolean'},\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n dragHandleLabel: {\n description:\n 'Accessible label for the drag handle — used as `aria-label` and tooltip text. Pass a translated string for i18n.',\n control: {type: 'text'},\n table: {\n type: {summary: 'string'},\n defaultValue: {summary: '\\'Drag to move\\''},\n },\n },\n classNames: {\n description:\n 'Class names to override or extend internal elements (e.g. from parent CSS modules).',\n control: {type: 'object'},\n table: {\n type: {summary: '{wrapper?: string; dragHandle?: string}'},\n },\n },\n onKeyboardReorder: {\n description:\n 'Called with `\"up\"` or `\"down\"` when the user presses ArrowUp/ArrowLeft or ArrowDown/ArrowRight while the item is keyboard-grabbed. Use this to reorder the list in state.',\n table: {\n type: {summary: '(direction: \\'up\\' | \\'down\\') => void'},\n },\n },\n onDragStart: {\n description:\n 'Standard HTML `dragstart` event handler. Set `isDragging` and store the dragging id here.',\n table: {\n type: {summary: 'React.DragEventHandler<HTMLDivElement>'},\n },\n },\n onDragEnd: {\n description:\n 'Standard HTML `dragend` event handler. Commit the reorder and clear `isDragging` here.',\n table: {\n type: {summary: 'React.DragEventHandler<HTMLDivElement>'},\n },\n },\n onDragOver: {\n description:\n 'Standard HTML `dragover` event handler. Call `e.preventDefault()` and store the current drop target id here.',\n table: {\n type: {summary: 'React.DragEventHandler<HTMLDivElement>'},\n },\n },\n onDrop: {\n description:\n 'Standard HTML `drop` event handler. Call `e.preventDefault()` to allow the drop.',\n table: {\n type: {summary: 'React.DragEventHandler<HTMLDivElement>'},\n },\n },\n testId: {\n description:\n 'Test ID for the component root. The drag handle receives `{testId}-drag-handle`.',\n control: {type: 'text'},\n table: {\n type: {summary: 'string'},\n },\n },\n },\n parameters: {\n docs: {\n subtitle: 'Generic drag-to-reorder wrapper for any component.',\n description: {\n component: `\n\\`\\`\\`js\nimport { DraggableWrapper } from \"@spaced-out/ui-design-system/lib/components/DraggableWrapper\";\n\\`\\`\\`\n\\`DraggableWrapper\\` adds drag-to-reorder behavior to any component without modifying it.\nIt shows a grip handle on hover and applies the dragging visual state\n(50% opacity + purple ring) when \\`isDragging\\` is \\`true\\`.\n\nThe parent manages all drag logic — pass the standard HTML drag event handlers\nand control item order in state.\n\n### Mouse usage\n\n\\`\\`\\`jsx\nconst [draggingId, setDraggingId] = React.useState(null);\nconst draggingIdRef = React.useRef(null);\nconst dragOverIdRef = React.useRef(null);\n\n<DraggableWrapper\n isDragging={draggingId === item.id}\n onDragStart={() => { setDraggingId(item.id); draggingIdRef.current = item.id; }}\n onDragEnd={() => { /* reorder logic */ setDraggingId(null); }}\n onDragOver={(e) => { e.preventDefault(); dragOverIdRef.current = item.id; }}\n onDrop={(e) => e.preventDefault()}\n onKeyboardReorder={(direction) => { /* move item up or down in state */ }}\n>\n <YourComponent />\n</DraggableWrapper>\n\\`\\`\\`\n\n### Keyboard usage\n\nTab to the grip handle, press **Enter** or **Space** to grab, **Arrow keys** to move, **Enter/Space** or **Escape** to drop.\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/DraggableWrapper/DraggableWrapper',\n },\n },\n};\n\n// ── Reorder helpers ────────────────────────────────────────────\n\nfunction reorder<T>(\n list: T[],\n fromId: string,\n toId: string,\n getId: (item: T) => string,\n): T[] {\n const next = [...list];\n const from = next.findIndex((item) => getId(item) === fromId);\n const to = next.findIndex((item) => getId(item) === toId);\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n}\n\nfunction moveItem<T>(\n list: T[],\n id: string,\n direction: 'up' | 'down',\n getId: (item: T) => string,\n): T[] {\n const next = [...list];\n const index = next.findIndex((item) => getId(item) === id);\n const swapIndex = direction === 'up' ? index - 1 : index + 1;\n if (swapIndex < 0 || swapIndex >= next.length) {\n return next;\n }\n [next[index], next[swapIndex]] = [next[swapIndex], next[index]];\n return next;\n}\n\n// ── KPI tiles ─────────────────────────────────────────────────\n\ninterface KPITile {\n id: string;\n iconName: string;\n topContent: string;\n middleContent: string;\n bottomContent: string;\n}\n\nconst INITIAL_KPI_TILES: KPITile[] = [\n {\n id: '1',\n iconName: 'users',\n topContent: 'Total Users',\n middleContent: '10,000',\n bottomContent: '10% (1,000 total)',\n },\n {\n id: '2',\n iconName: 'money-bill',\n topContent: 'Total Sales',\n middleContent: '$1,234,567',\n bottomContent: '5% (500 total)',\n },\n {\n id: '3',\n iconName: 'chart-bar',\n topContent: 'Active Sessions',\n middleContent: '3,421',\n bottomContent: '2% (68 total)',\n },\n];\n\nexport const WithKPIBoxes = () => {\n const [tiles, setTiles] = React.useState<KPITile[]>(INITIAL_KPI_TILES);\n const [draggingId, setDraggingId] = React.useState<string | null>(null);\n const draggingIdRef = React.useRef<string | null>(null);\n const dragOverIdRef = React.useRef<string | null>(null);\n\n const handleKpiDragEnd = () => {\n const fromId = draggingIdRef.current;\n const toId = dragOverIdRef.current;\n if (fromId && toId && fromId !== toId) {\n setTiles((prev) => reorder(prev, fromId, toId, (t) => t.id));\n }\n setDraggingId(null);\n draggingIdRef.current = null;\n dragOverIdRef.current = null;\n };\n\n return (\n <div className={css.row}>\n {tiles.map((tile) => (\n <DraggableWrapper\n key={tile.id}\n isDragging={draggingId === tile.id}\n testId={`kpi-draggable-${tile.id}`}\n onDragStart={() => {\n setDraggingId(tile.id);\n draggingIdRef.current = tile.id;\n }}\n onDragEnd={handleKpiDragEnd}\n onDragOver={(e) => {\n e.preventDefault();\n dragOverIdRef.current = tile.id;\n }}\n onDrop={(e) => e.preventDefault()}\n onKeyboardReorder={(direction) => {\n setTiles((prev) => moveItem(prev, tile.id, direction, (t) => t.id));\n }}\n >\n <KPIBox\n iconName={tile.iconName}\n iconType=\"duotone\"\n topContent={tile.topContent}\n middleContent={tile.middleContent}\n bottomContent={\n <div className={css.bottomContent}>\n <Icon size=\"small\" name=\"arrow-right-long\" color=\"neutral\" />\n <span>{tile.bottomContent}</span>\n </div>\n }\n classNames={{wrapper: css.noWrapperBorder}}\n />\n </DraggableWrapper>\n ))}\n </div>\n );\n};\nWithKPIBoxes.storyName = 'With KPI Boxes';\n\n// ── Tables ────────────────────────────────────────────────────\n\ninterface RowData extends GenericObject {\n id: string;\n name: string;\n email: string;\n}\n\nconst NameCell = ({data}: {data: RowData}) => (\n <BasicSingleCell>\n <BodySmall color={TEXT_COLORS.secondary}>{data.name}</BodySmall>\n </BasicSingleCell>\n);\n\nconst EmailCell = ({data}: {data: RowData}) => (\n <BasicSingleCell>\n <BodyMediumBold>{data.email}</BodyMediumBold>\n </BasicSingleCell>\n);\n\nconst tableHeaders = [\n {label: 'Name', key: 'name', sortable: false, render: NameCell},\n {label: 'Email', key: 'email', sortable: false, render: EmailCell},\n];\n\ninterface DraggableTable {\n id: string;\n entries: RowData[];\n}\n\nconst INITIAL_TABLES: DraggableTable[] = [\n {\n id: 't1',\n entries: [\n {id: 't1-1', name: 'Alice Johnson', email: 'alice@eng.com'},\n {id: 't1-2', name: 'Bob Smith', email: 'bob@eng.com'},\n {id: 't1-3', name: 'Carol White', email: 'carol@eng.com'},\n ],\n },\n {\n id: 't2',\n entries: [\n {id: 't2-1', name: 'David Lee', email: 'david@mkt.com'},\n {id: 't2-2', name: 'Emma Davis', email: 'emma@mkt.com'},\n {id: 't2-3', name: 'Frank Brown', email: 'frank@mkt.com'},\n ],\n },\n {\n id: 't3',\n entries: [\n {id: 't3-1', name: 'Grace Kim', email: 'grace@sales.com'},\n {id: 't3-2', name: 'Henry Wilson', email: 'henry@sales.com'},\n {id: 't3-3', name: 'Iris Chen', email: 'iris@sales.com'},\n ],\n },\n];\n\nexport const WithTables = () => {\n const [tables, setTables] = React.useState<DraggableTable[]>(INITIAL_TABLES);\n const [draggingId, setDraggingId] = React.useState<string | null>(null);\n const draggingIdRef = React.useRef<string | null>(null);\n const dragOverIdRef = React.useRef<string | null>(null);\n\n const handleDragEnd = () => {\n const fromId = draggingIdRef.current;\n const toId = dragOverIdRef.current;\n if (fromId && toId && fromId !== toId) {\n setTables((prev) => reorder(prev, fromId, toId, (t) => t.id));\n }\n setDraggingId(null);\n draggingIdRef.current = null;\n dragOverIdRef.current = null;\n };\n\n return (\n <div className={css.column}>\n {tables.map((table) => (\n <DraggableWrapper\n key={table.id}\n isDragging={draggingId === table.id}\n classNames={{wrapper: css.tableWrapper}}\n testId={`table-draggable-${table.id}`}\n onDragStart={() => {\n setDraggingId(table.id);\n draggingIdRef.current = table.id;\n }}\n onDragEnd={handleDragEnd}\n onDragOver={(e) => {\n e.preventDefault();\n dragOverIdRef.current = table.id;\n }}\n onDrop={(e) => e.preventDefault()}\n onKeyboardReorder={(direction) => {\n setTables((prev) =>\n moveItem(prev, table.id, direction, (t) => t.id),\n );\n }}\n >\n <Table<RowData, GenericObject>\n headers={tableHeaders}\n entries={table.entries}\n sortable={false}\n classNames={{wrapper: css.noWrapperBorder}}\n />\n </DraggableWrapper>\n ))}\n </div>\n );\n};\nWithTables.storyName = 'With Tables';\n\n// ── Chart + Table row ─────────────────────────────────────────\n\nconst columnChartSeries = [\n {\n name: 'Inbound Sourced',\n data: [\n {name: 'Q1.23', y: 40629},\n {name: 'Q2.23', y: 26000},\n {name: 'Q3.23', y: 10700},\n {name: 'Q4.23', y: 38300},\n ],\n },\n {\n name: 'Outbound Sourced',\n data: [\n {name: 'Q1.23', y: 31086},\n {name: 'Q2.23', y: 13600},\n {name: 'Q3.23', y: 45000},\n {name: 'Q4.23', y: 41000},\n ],\n },\n];\n\nconst columnChartXAxis = {title: {text: 'Quarter'}};\nconst columnChartYAxis = {title: {text: 'Amount Sourced'}};\nconst columnChartLegend = {enabled: true, shadow: false};\n\nconst CHART_AND_TABLE_ENTRIES: RowData[] = [\n {id: 'r1', name: 'Alice Johnson', email: 'alice@example.com'},\n {id: 'r2', name: 'Bob Smith', email: 'bob@example.com'},\n {id: 'r3', name: 'Carol White', email: 'carol@example.com'},\n {id: 'r4', name: 'David Lee', email: 'david@example.com'},\n {id: 'r5', name: 'Emma Davis', email: 'emma@example.com'},\n {id: 'r6', name: 'Frank Brown', email: 'frank@example.com'},\n {id: 'r7', name: 'Grace Kim', email: 'grace@example.com'},\n {id: 'r8', name: 'Henry Wilson', email: 'henry@example.com'},\n {id: 'r9', name: 'Iris Chen', email: 'iris@example.com'},\n {id: 'r10', name: 'Jack Martinez', email: 'jack@example.com'},\n];\n\ntype WidgetId = 'chart' | 'table';\n\nconst WIDGET_ORDER: WidgetId[] = ['chart', 'table'];\n\nexport const WithChartAndTable = () => {\n const [widgetOrder, setWidgetOrder] =\n React.useState<WidgetId[]>(WIDGET_ORDER);\n const [draggingId, setDraggingId] = React.useState<WidgetId | null>(null);\n const draggingIdRef = React.useRef<WidgetId | null>(null);\n const dragOverIdRef = React.useRef<WidgetId | null>(null);\n\n const handleDragEnd = () => {\n const fromId = draggingIdRef.current;\n const toId = dragOverIdRef.current;\n if (fromId && toId && fromId !== toId) {\n setWidgetOrder((prev) => reorder(prev, fromId, toId, (id) => id));\n }\n setDraggingId(null);\n draggingIdRef.current = null;\n dragOverIdRef.current = null;\n };\n\n return (\n <div className={classify(css.row, css.rowEqualHeight)}>\n {widgetOrder.map((widgetId) =>\n widgetId === 'chart' ? (\n <DraggableWrapper\n key=\"chart\"\n classNames={{\n wrapper: css.widgetWrapper,\n dragHandle: css.dragHandleChart,\n }}\n testId=\"widget-chart-1\"\n isDragging={draggingId === 'chart'}\n onDragStart={() => {\n setDraggingId('chart');\n draggingIdRef.current = 'chart';\n }}\n onDragEnd={handleDragEnd}\n onDragOver={(e) => {\n e.preventDefault();\n dragOverIdRef.current = 'chart';\n }}\n onDrop={(e) => e.preventDefault()}\n onKeyboardReorder={(direction) => {\n setWidgetOrder((prev) =>\n moveItem(prev, 'chart', direction, (id) => id),\n );\n }}\n >\n <ColumnChart\n cardTitle=\"Trend\"\n series={columnChartSeries}\n xAxis={columnChartXAxis}\n yAxis={columnChartYAxis}\n legend={columnChartLegend}\n classNames={{wrapper: css.noWrapperBorder}}\n />\n </DraggableWrapper>\n ) : (\n <DraggableWrapper\n key=\"table\"\n classNames={{wrapper: css.widgetWrapper}}\n testId=\"widget-table-1\"\n isDragging={draggingId === 'table'}\n onDragStart={() => {\n setDraggingId('table');\n draggingIdRef.current = 'table';\n }}\n onDragEnd={handleDragEnd}\n onDragOver={(e) => {\n e.preventDefault();\n dragOverIdRef.current = 'table';\n }}\n onDrop={(e) => e.preventDefault()}\n onKeyboardReorder={(direction) => {\n setWidgetOrder((prev) =>\n moveItem(prev, 'table', direction, (id) => id),\n );\n }}\n >\n <Table<RowData, GenericObject>\n headers={tableHeaders}\n entries={CHART_AND_TABLE_ENTRIES}\n sortable={false}\n classNames={{wrapper: css.noWrapperBorder}}\n />\n </DraggableWrapper>\n ),\n )}\n </div>\n );\n};\nWithChartAndTable.storyName = 'With Chart And Table';\n"
|
|
918
|
+
},
|
|
919
|
+
"css": {
|
|
920
|
+
"path": "DraggableWrapper.module.css",
|
|
921
|
+
"content": "@value (colorBorderTertiary, colorFillPrimary, colorButtonFillSecondaryPressed) from '../../styles/variables/_color.css';\n@value (spaceSmall) from '../../styles/variables/_space.css';\n@value (borderRadiusMedium, borderWidthPrimary, borderWidthTertiary) from '../../styles/variables/_border.css';\n@value (motionDurationNormal, motionEaseInEaseOut) from '../../styles/variables/_motion.css';\n@value (opacity50, opacity100, opacity0) from '../../styles/variables/_opacity.css';\n@value (elevationCard) from '../../styles/variables/_elevation.css';\n\n.wrapper {\n position: relative;\n border: borderWidthPrimary solid colorBorderTertiary;\n border-radius: borderRadiusMedium;\n}\n\n.wrapper:hover:not(.dragging) {\n outline: borderWidthPrimary solid colorBorderTertiary;\n outline-offset: calc(-1 * borderWidthPrimary);\n}\n\n/* ── Drag handle ──────────────────────────────────────────── */\n\n.dragHandle {\n position: absolute;\n top: spaceSmall;\n left: borderWidthPrimary;\n opacity: opacity0;\n cursor: grab;\n transition: opacity motionDurationNormal motionEaseInEaseOut;\n line-height: 0;\n z-index: calc(elevationCard / 4);\n border-radius: borderRadiusMedium;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dragHandle {\n transition: none;\n }\n}\n\n.dragHandle:focus-within {\n opacity: opacity100;\n}\n\n.wrapper:hover .dragHandle {\n opacity: opacity100;\n}\n\n/* ── Dragging state ───────────────────────────────────────── */\n\n.wrapper.dragging {\n opacity: opacity50;\n border: borderWidthPrimary solid colorFillPrimary;\n outline: borderWidthTertiary solid colorButtonFillSecondaryPressed;\n outline-offset: borderWidthPrimary;\n}\n\n.wrapper.dragging .dragHandle {\n opacity: opacity100;\n cursor: grabbing;\n}\n"
|
|
922
|
+
},
|
|
923
|
+
"index": {
|
|
924
|
+
"path": "index.d.ts",
|
|
925
|
+
"content": "export { DraggableWrapper } from '../../components/DraggableWrapper/DraggableWrapper';\nexport type { DraggableWrapperProps, DraggableWrapperClassNames, } from '../../components/DraggableWrapper/DraggableWrapper';\n//# sourceMappingURL=index.d.ts.map"
|
|
926
|
+
},
|
|
927
|
+
"additional": {}
|
|
928
|
+
},
|
|
929
|
+
"allFiles": [
|
|
930
|
+
"DraggableWrapper.module.css",
|
|
931
|
+
"DraggableWrapper.stories.module.css",
|
|
932
|
+
"DraggableWrapper.stories.tsx",
|
|
933
|
+
"DraggableWrapper.tsx",
|
|
934
|
+
"index.ts"
|
|
935
|
+
]
|
|
936
|
+
},
|
|
889
937
|
"Dropdown": {
|
|
890
938
|
"name": "Dropdown",
|
|
891
939
|
"path": "src/components/Dropdown",
|
|
@@ -1263,7 +1311,7 @@
|
|
|
1263
1311
|
},
|
|
1264
1312
|
"css": {
|
|
1265
1313
|
"path": "Icon.module.css",
|
|
1266
|
-
"content": "@value (\n colorInformation,\n colorSuccess,\n colorWarning,\n colorDanger,\n colorNeutral,\n colorTextPrimary,\n colorTextSecondary,\n colorTextTertiary,\n colorTextDisabled,\n colorTextClickable,\n colorTextInversePrimary,\n colorTextInverseSecondary,\n colorTextFavorite\n) from '../../styles/variables/_color.css';\n\n.primary {\n color: colorTextPrimary;\n}\n\n.secondary {\n color: colorTextSecondary;\n}\n\n.tertiary {\n color: colorTextTertiary;\n}\n\n.disabled {\n color: colorTextDisabled;\n}\n\n.clickable {\n color: colorTextClickable;\n}\n\n.information {\n color: colorInformation;\n}\n\n.success {\n color: colorSuccess;\n}\n\n.warning {\n color: colorWarning;\n}\n\n.danger {\n color: colorDanger;\n}\n\n.neutral {\n color: colorNeutral;\n}\n\n.inversePrimary {\n color: colorTextInversePrimary;\n}\n\n.inverseSecondary {\n color: colorTextInverseSecondary;\n}\n\n.favorite {\n color: colorTextFavorite;\n}\n"
|
|
1314
|
+
"content": "@value (\n colorInformation,\n colorSuccess,\n colorWarning,\n colorDanger,\n colorNeutral,\n colorTextPrimary,\n colorTextSecondary,\n colorTextTertiary,\n colorTextDisabled,\n colorTextClickable,\n colorTextInversePrimary,\n colorTextInverseSecondary,\n colorTextFavorite\n) from '../../styles/variables/_color.css';\n\n.primary {\n color: colorTextPrimary;\n}\n\n.secondary {\n color: colorTextSecondary;\n}\n\n.tertiary {\n color: colorTextTertiary;\n}\n\n.disabled {\n color: colorTextDisabled;\n}\n\n.clickable {\n color: colorTextClickable;\n}\n\n.information {\n color: colorInformation;\n}\n\n.success {\n color: colorSuccess;\n}\n\n.warning {\n color: colorWarning;\n}\n\n.danger {\n color: colorDanger;\n}\n\n.neutral {\n color: colorNeutral;\n}\n\n.inversePrimary {\n color: colorTextInversePrimary;\n}\n\n.inverseSecondary {\n color: colorTextInverseSecondary;\n}\n\n.favorite {\n color: colorTextFavorite;\n}\n\n.inherit {\n color: inherit;\n}\n"
|
|
1267
1315
|
},
|
|
1268
1316
|
"index": {
|
|
1269
1317
|
"path": "index.d.ts",
|
|
@@ -1585,7 +1633,7 @@
|
|
|
1585
1633
|
"files": {
|
|
1586
1634
|
"main": {
|
|
1587
1635
|
"path": "Modal.d.ts",
|
|
1588
|
-
"content": "import * as React from 'react';\nimport type { UseTransitionStylesProps } from '@floating-ui/react';\ntype ClassNames = Readonly<{\n container?: string;\n content?: string;\n backdrop?: string;\n}>;\ntype FooterClassNames = Readonly<{\n wrapper?: string;\n actions?: string;\n}>;\nexport interface ModalProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n isOpen?: boolean;\n onClose?: ((arg1: React.SyntheticEvent<HTMLElement>) => unknown) | null | undefined;\n hideBackdrop?: boolean;\n tapOutsideToClose?: boolean;\n allowBackgroundInteraction?: boolean;\n initialFocus?: number;\n customAnimation?: UseTransitionStylesProps;\n testId?: string;\n}\nexport type ModalSize = 'small' | 'medium' | 'large';\nexport type OverlayType = 'Modal' | 'Dialog' | 'Panel';\nexport type OverlaySize = 'small' | 'medium' | 'large' | 'fullscreen';\nexport type OverlayAnchor = 'left' | 'right';\nexport interface OverlayEventDetail {\n /** Stable identifier to correlate mount/unmount pairs */\n id: string;\n overlayType: OverlayType;\n size?: OverlaySize;\n anchor?: OverlayAnchor;\n /** Whether the overlay renders a visible backdrop */\n hasBackdrop: boolean;\n tapOutsideToClose: boolean;\n allowBackgroundInteraction: boolean;\n /** Dialog semantic
|
|
1636
|
+
"content": "import * as React from 'react';\nimport type { UseTransitionStylesProps } from '@floating-ui/react';\ntype ClassNames = Readonly<{\n container?: string;\n content?: string;\n backdrop?: string;\n}>;\ntype FooterClassNames = Readonly<{\n wrapper?: string;\n actions?: string;\n}>;\nexport interface ModalProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n isOpen?: boolean;\n onClose?: ((arg1: React.SyntheticEvent<HTMLElement>) => unknown) | null | undefined;\n hideBackdrop?: boolean;\n tapOutsideToClose?: boolean;\n allowBackgroundInteraction?: boolean;\n initialFocus?: number;\n customAnimation?: UseTransitionStylesProps;\n testId?: string;\n}\nexport type ModalSize = 'small' | 'medium' | 'large';\nexport type OverlayType = 'Modal' | 'Dialog' | 'Panel';\nexport type OverlaySize = 'small' | 'medium' | 'large' | 'fullscreen';\nexport type OverlayAnchor = 'left' | 'right';\nexport interface OverlayEventDetail {\n /** Stable identifier to correlate mount/unmount pairs */\n id: string;\n overlayType: OverlayType;\n size?: OverlaySize;\n anchor?: OverlayAnchor;\n /** Whether the overlay renders a visible backdrop */\n hasBackdrop: boolean;\n tapOutsideToClose: boolean;\n allowBackgroundInteraction: boolean;\n /** Dialog semantic (neutral, success, warning, danger, information) */\n semantic?: string;\n testId?: string;\n}\nexport declare const OVERLAY_MOUNT_EVENT: \"ds:overlay:mount\";\nexport declare const OVERLAY_UNMOUNT_EVENT: \"ds:overlay:unmount\";\nexport type OverlayMountEvent = CustomEvent<OverlayEventDetail>;\nexport type OverlayUnmountEvent = CustomEvent<OverlayEventDetail>;\ndeclare global {\n interface WindowEventMap {\n 'ds:overlay:mount': OverlayMountEvent;\n 'ds:overlay:unmount': OverlayUnmountEvent;\n }\n}\nexport interface BaseModalProps extends Omit<ModalProps, 'size'> {\n size?: ModalSize;\n /** @internal Used by Panel/Dialog to identify overlay type in lifecycle events */\n overlayType?: OverlayType;\n /** @internal Used by Panel/Dialog to report size in lifecycle events */\n overlaySize?: OverlaySize;\n /** @internal Used by Panel to report anchor in lifecycle events */\n overlayAnchor?: OverlayAnchor;\n /** @internal Used by Dialog to report semantic variant in lifecycle events */\n overlaySemantic?: string;\n}\nexport interface ModalHeaderProps {\n children?: React.ReactNode;\n hideCloseBtn?: boolean;\n onCloseButtonClick?: React.MouseEventHandler<HTMLButtonElement>;\n className?: string;\n testId?: string;\n}\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n classNames?: FooterClassNames;\n testId?: string;\n}\nexport interface ModalBodyProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport declare const ModalHeader: ({ children, hideCloseBtn, onCloseButtonClick, className, testId, }: ModalHeaderProps) => React.JSX.Element;\nexport declare const ModalBody: ({ children, className, testId }: ModalBodyProps) => React.JSX.Element;\nexport declare const ModalFooter: ({ children, classNames, testId, }: ModalFooterProps) => React.JSX.Element;\nexport declare const Modal: ({ classNames, children, isOpen, onClose, hideBackdrop, tapOutsideToClose, initialFocus, customAnimation, allowBackgroundInteraction, testId, size, overlayType, overlaySize, overlayAnchor, overlaySemantic, }: BaseModalProps) => React.ReactPortal | null;\nexport declare const FullScreenModal: ({ classNames, testId, ...props }: ModalProps) => React.JSX.Element;\nexport {};\n//# sourceMappingURL=Modal.d.ts.map"
|
|
1589
1637
|
},
|
|
1590
1638
|
"story": {
|
|
1591
1639
|
"path": "Modal.stories.tsx",
|
|
@@ -1681,7 +1729,7 @@
|
|
|
1681
1729
|
"files": {
|
|
1682
1730
|
"main": {
|
|
1683
1731
|
"path": "PageTitle.d.ts",
|
|
1684
|
-
"content": "import * as React from 'react';\nimport type { Flow } from 'flow-to-typescript-codemod';\ntype ClassNames = Readonly<{\n wrapper?: string;\n leftSlot?: string;\n rightSlot?: string;\n}>;\nexport interface PageTitleProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n pageNameKey?: string;\n showBackButton?: boolean;\n onBack?: () => void;\n testId?: string;\n}\nexport declare const PAGE_NAME_LIST: Readonly<{\n dashboard: {\n title: string;\n iconName: string;\n iconType: string;\n };\n engage: {\n title: string;\n iconName: string;\n iconType: string;\n };\n journeys: {\n title: string;\n iconName: string;\n iconType: string;\n };\n workflows: {\n title: string;\n iconName: string;\n iconType: string;\n };\n trm: {\n title: string;\n iconName: string;\n iconType: string;\n };\n analytics: {\n title: string;\n iconName: string;\n iconType: string;\n };\n messaging: {\n title: string;\n iconName: string;\n iconType: string;\n };\n chatbot: {\n title: string;\n iconName: string;\n iconType: string;\n };\n referrals: {\n title: string;\n iconName: string;\n iconType: string;\n };\n records: {\n title: string;\n iconName: string;\n iconType: string;\n };\n bulkCleanup: {\n title: string;\n iconName: string;\n iconType: string;\n };\n support: {\n title: string;\n iconName: string;\n iconType: string;\n };\n audit: {\n title: string;\n iconName: string;\n iconType: string;\n };\n timeline: {\n title: string;\n iconName: string;\n iconType: string;\n };\n people: {\n title: string;\n iconName: string;\n iconType: string;\n };\n jobs: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts: {\n title: string;\n iconName: string;\n iconType: string;\n };\n meetings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts3: {\n title: string;\n iconName: string;\n iconType: string;\n };\n tracking: {\n title: string;\n iconName: string;\n iconType: string;\n };\n earnings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n settings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n broadcast: {\n title: string;\n iconName: string;\n iconType: string;\n };\n}>;\nexport interface TabSlotProps {\n children?: React.ReactNode;\n className: string;\n testId?: string;\n}\nexport declare const TabSlot: {\n ({ children, className, testId, ...props }: TabSlotProps): React.JSX.Element;\n displayName: string;\n};\nexport interface RightSlotProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport declare const RightSlot: {\n ({ children, testId, ...props }: RightSlotProps): React.JSX.Element;\n displayName: string;\n};\nexport interface PageNameProps {\n children?: React.ReactNode;\n testId?: string;\n}\nexport declare const PageName: {\n ({ children, testId, ...props }: PageNameProps): React.JSX.Element;\n displayName: string;\n};\nexport declare const PageTitle: Flow.AbstractComponent<PageTitleProps, HTMLDivElement>;\nexport {};\n//# sourceMappingURL=PageTitle.d.ts.map"
|
|
1732
|
+
"content": "import * as React from 'react';\nimport type { Flow } from 'flow-to-typescript-codemod';\ntype ClassNames = Readonly<{\n wrapper?: string;\n leftSlot?: string;\n rightSlot?: string;\n}>;\nexport interface PageTitleProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n pageNameKey?: string;\n showBackButton?: boolean;\n onBack?: () => void;\n testId?: string;\n}\nexport declare const PAGE_NAME_LIST: Readonly<{\n dashboard: {\n title: string;\n iconName: string;\n iconType: string;\n };\n tasks: {\n title: string;\n iconName: string;\n iconType: string;\n };\n engage: {\n title: string;\n iconName: string;\n iconType: string;\n };\n journeys: {\n title: string;\n iconName: string;\n iconType: string;\n };\n workflows: {\n title: string;\n iconName: string;\n iconType: string;\n };\n trm: {\n title: string;\n iconName: string;\n iconType: string;\n };\n analytics: {\n title: string;\n iconName: string;\n iconType: string;\n };\n messaging: {\n title: string;\n iconName: string;\n iconType: string;\n };\n chatbot: {\n title: string;\n iconName: string;\n iconType: string;\n };\n referrals: {\n title: string;\n iconName: string;\n iconType: string;\n };\n records: {\n title: string;\n iconName: string;\n iconType: string;\n };\n bulkCleanup: {\n title: string;\n iconName: string;\n iconType: string;\n };\n support: {\n title: string;\n iconName: string;\n iconType: string;\n };\n audit: {\n title: string;\n iconName: string;\n iconType: string;\n };\n timeline: {\n title: string;\n iconName: string;\n iconType: string;\n };\n people: {\n title: string;\n iconName: string;\n iconType: string;\n };\n jobs: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts: {\n title: string;\n iconName: string;\n iconType: string;\n };\n meetings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts3: {\n title: string;\n iconName: string;\n iconType: string;\n };\n tracking: {\n title: string;\n iconName: string;\n iconType: string;\n };\n earnings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n settings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n broadcast: {\n title: string;\n iconName: string;\n iconType: string;\n };\n}>;\nexport interface TabSlotProps {\n children?: React.ReactNode;\n className: string;\n testId?: string;\n}\nexport declare const TabSlot: {\n ({ children, className, testId, ...props }: TabSlotProps): React.JSX.Element;\n displayName: string;\n};\nexport interface RightSlotProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport declare const RightSlot: {\n ({ children, testId, ...props }: RightSlotProps): React.JSX.Element;\n displayName: string;\n};\nexport interface PageNameProps {\n children?: React.ReactNode;\n testId?: string;\n}\nexport declare const PageName: {\n ({ children, testId, ...props }: PageNameProps): React.JSX.Element;\n displayName: string;\n};\nexport declare const PageTitle: Flow.AbstractComponent<PageTitleProps, HTMLDivElement>;\nexport {};\n//# sourceMappingURL=PageTitle.d.ts.map"
|
|
1685
1733
|
},
|
|
1686
1734
|
"story": {
|
|
1687
1735
|
"path": "PageTitle.stories.tsx",
|
|
@@ -1719,7 +1767,7 @@
|
|
|
1719
1767
|
},
|
|
1720
1768
|
"css": {
|
|
1721
1769
|
"path": "Pagination.module.css",
|
|
1722
|
-
"content": "@value (colorFillPrimary, colorTextSecondary, colorTextDisabled) from '../../styles/variables/_color.css';\n@value (spaceXXSmall, spaceNone, spaceSmall, spaceXSmall) from '../../styles/variables/_space.css';\n@value (size34, sizeFluid, size40) from '../../styles/variables/_size.css';\n\n.wrapper {\n display: flex;\n align-items: center;\n width: sizeFluid;\n height: fit-content;\n justify-content: space-between;\n}\n\n.childrenSlot {\n display: flex;\n}\n\n.paginatorSlot {\n display: flex;\n gap: spaceXXSmall;\n}\n\n.paginatorSlots {\n display: flex;\n gap: spaceSmall;\n}\n\n.secondaryLabel {\n margin-right: spaceXSmall;\n}\n\n.paginatorButton {\n min-width: size34;\n padding: spaceNone;\n color: colorTextSecondary;\n}\n\n.pageNumbers {\n display: flex;\n align-items: center;\n gap: spaceXXSmall;\n}\n\n.separator {\n display: flex;\n width: size34;\n height: size34;\n align-items: center;\n justify-content: center;\n}\n\n.paginatorButton.disabled {\n background-color: initial;\n}\n\n.paginatorButton.selected {\n pointer-events: none;\n}\n\n.icon {\n color: colorTextSecondary;\n}\n\n.icon.disabled {\n color: colorTextDisabled;\n}\n\n.dropdownWrapper {\n width: calc(size40 * 2);\n}\n\n.menuWrapper {\n min-width: calc(size40 * 2);\n}\n"
|
|
1770
|
+
"content": "@value (colorFillPrimary, colorTextSecondary, colorTextDisabled) from '../../styles/variables/_color.css';\n@value (spaceXXSmall, spaceNone, spaceSmall, spaceXSmall) from '../../styles/variables/_space.css';\n@value (size34, sizeFluid, size40) from '../../styles/variables/_size.css';\n\n.wrapper {\n display: flex;\n align-items: center;\n width: sizeFluid;\n height: fit-content;\n justify-content: space-between;\n}\n\n.wrapperCompact {\n justify-content: center;\n}\n\n.childrenSlot {\n display: flex;\n}\n\n.paginatorSlot {\n display: flex;\n gap: spaceXXSmall;\n}\n\n.paginatorSlots {\n display: flex;\n align-items: center;\n gap: spaceSmall;\n}\n\n.secondaryLabel {\n margin-right: spaceXSmall;\n}\n\n.paginatorButton {\n min-width: size34;\n padding: spaceNone;\n color: colorTextSecondary;\n}\n\n.pageNumbers {\n display: flex;\n align-items: center;\n gap: spaceXXSmall;\n}\n\n.separator {\n display: flex;\n width: size34;\n height: size34;\n align-items: center;\n justify-content: center;\n}\n\n.paginatorButton.disabled {\n background-color: initial;\n}\n\n.paginatorButton.selected {\n pointer-events: none;\n}\n\n.icon {\n color: colorTextSecondary;\n}\n\n.icon.disabled {\n color: colorTextDisabled;\n}\n\n.dropdownWrapper {\n width: calc(size40 * 2);\n}\n\n.menuWrapper {\n min-width: calc(size40 * 2);\n}\n"
|
|
1723
1771
|
},
|
|
1724
1772
|
"index": {
|
|
1725
1773
|
"path": "index.d.ts",
|
|
@@ -1747,15 +1795,15 @@
|
|
|
1747
1795
|
"files": {
|
|
1748
1796
|
"main": {
|
|
1749
1797
|
"path": "Panel.d.ts",
|
|
1750
|
-
"content": "import * as React from 'react';\nimport type { Flow } from 'flow-to-typescript-codemod';\nimport type { ModalProps } from '../../components/Modal';\nexport type PanelSize = 'small' | 'medium' | 'large';\nexport type PanelAnchor = 'left' | 'right';\nexport interface PanelHeaderProps {\n children?: React.ReactNode;\n hideCloseBtn?: boolean;\n onCloseButtonClick?: React.MouseEventHandler<HTMLButtonElement>;\n className?: string;\n size?: 'medium' | 'small';\n testId?: string;\n}\ntype FooterClassNames = Readonly<{\n wrapper?: string;\n actions?: string;\n}>;\nexport interface PanelFooterProps {\n children?: React.ReactNode;\n classNames?: FooterClassNames;\n testId?: string;\n}\nexport interface PanelBodyProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport interface PanelProps extends Omit<ModalProps, 'allowBackgroundInteraction' | 'size' | 'anchor'> {\n allowBackgroundInteraction?: boolean;\n size?: PanelSize;\n anchor?: PanelAnchor;\n testId?: string;\n}\nexport declare const PanelHeader: ({ children, hideCloseBtn, onCloseButtonClick, className, size, testId, }: PanelHeaderProps) => React.JSX.Element;\nexport declare const PanelBody: Flow.AbstractComponent<PanelBodyProps, HTMLDivElement>;\nexport declare const PanelFooter: ({ children, classNames, testId, }: PanelFooterProps) => React.JSX.Element;\nexport declare const Panel: ({ children, isOpen, size, anchor, onClose, hideBackdrop, classNames, customAnimation, tapOutsideToClose, allowBackgroundInteraction, testId, ...restPanelProps }: PanelProps) => React.JSX.Element;\nexport {};\n//# sourceMappingURL=Panel.d.ts.map"
|
|
1798
|
+
"content": "import * as React from 'react';\nimport type { Flow } from 'flow-to-typescript-codemod';\nimport type { ModalProps } from '../../components/Modal';\nexport type PanelSize = 'small' | 'medium' | 'large';\nexport type PanelAnchor = 'left' | 'right';\nexport interface PanelHeaderProps {\n children?: React.ReactNode;\n hideCloseBtn?: boolean;\n onCloseButtonClick?: React.MouseEventHandler<HTMLButtonElement>;\n className?: string;\n size?: 'medium' | 'small';\n testId?: string;\n leftSlot?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\ntype FooterClassNames = Readonly<{\n wrapper?: string;\n actions?: string;\n}>;\nexport interface PanelFooterProps {\n children?: React.ReactNode;\n classNames?: FooterClassNames;\n testId?: string;\n}\nexport interface PanelBodyProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport interface PanelProps extends Omit<ModalProps, 'allowBackgroundInteraction' | 'size' | 'anchor'> {\n allowBackgroundInteraction?: boolean;\n size?: PanelSize;\n anchor?: PanelAnchor;\n testId?: string;\n}\nexport declare const PanelHeader: ({ children, hideCloseBtn, onCloseButtonClick, className, size, testId, rightSlot, leftSlot, }: PanelHeaderProps) => React.JSX.Element;\nexport declare const PanelBody: Flow.AbstractComponent<PanelBodyProps, HTMLDivElement>;\nexport declare const PanelFooter: ({ children, classNames, testId, }: PanelFooterProps) => React.JSX.Element;\nexport declare const Panel: ({ children, isOpen, size, anchor, onClose, hideBackdrop, classNames, customAnimation, tapOutsideToClose, allowBackgroundInteraction, testId, ...restPanelProps }: PanelProps) => React.JSX.Element;\nexport {};\n//# sourceMappingURL=Panel.d.ts.map"
|
|
1751
1799
|
},
|
|
1752
1800
|
"story": {
|
|
1753
1801
|
"path": "Panel.stories.tsx",
|
|
1754
|
-
"content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport {\n Dialog,\n DialogBody,\n DialogFooter,\n DialogHeader,\n} from 'src/components/Dialog';\nimport {SimpleDropdown} from 'src/components/Dropdown';\nimport {Input} from 'src/components/Input';\nimport type {PanelProps} from 'src/components/Panel/Panel';\nimport {\n Panel,\n PanelBody,\n PanelFooter,\n PanelHeader,\n} from 'src/components/Panel/Panel';\nimport {BodyLarge, SubTitleLarge} from 'src/components/Text';\nimport {Textarea} from 'src/components/Textarea';\nimport {Tooltip} from 'src/components/Tooltip';\n\nimport css from 'src/components/Panel/Panel.stories.module.css';\n\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Panel',\n argTypes: {\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n anchor: {\n options: ['left', 'right'],\n description: 'Position of Panel',\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'left'},\n },\n },\n allowBackgroundInteraction: {\n description:\n 'if **true**, allows interaction with the background content. This would remove the backdrop layer for the panel and set tapOutsideToClose to false',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n size: {\n description:\n 'Panel supports only three size variants namely small, medium and large. `small` < `medium` < `large`',\n options: ['small', 'medium', 'large'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'medium'},\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n customAnimation: {\n description: `\n\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n\\`customAnimation: UseTransitionStylesProps\\` prop for\nall your custom animation needs.\nIt defines the following properties:\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed.\n\nThis is the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Panel component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Panel, PanelBody, PanelHeader, PanelFooter } from \"@spaced-out/ui-design-system/lib/components/Panel\";\n\\`\\`\\`\nDestinations in the app are accessible through Panels. Panels are **side sheets**, which are attached to the left or\nright edge of the screen and are surfaces with extra content. Panels can either be permanently on-screen or controlled by an **action**.\n\nPanel is a variation of a **<a href=\"../?path=/docs/components-modal--docs\">Modal</a>** with additional animation, position and size overrides.\n\nSemantically a Panel component should be composed from \\`PanelHeader\\`, \\`PanelBody\\`, and \\`PanelFooter\\` **components**, these are nothing but layout components which defines\nappropriate spacing for the children living in them. \\`PanelHeader\\` adds a close icon by default and provides a callback on click. You can pass a prop to\nshow/hide the close button as well.\nEach of these components also exposes a className\n\n---\n\n### Overlay Lifecycle Events\n\nPanel emits **strongly-typed window events** when it mounts and unmounts (see **<a href=\"../?path=/docs/components-modal--docs\">Modal docs</a>** for the full API reference, all event types, and advanced usage patterns).\n\nPanel-specific fields in the event payload:\n\n| Field | Value |\n|---|---|\n| \\`overlayType\\` | \\`'Panel'\\` |\n| \\`size\\` | \\`'small' \\\\| 'medium' \\\\| 'large'\\` (from the \\`size\\` prop) |\n| \\`anchor\\` | \\`'left' \\\\| 'right'\\` (from the \\`anchor\\` prop) |\n| \\`hasBackdrop\\` | Derived from \\`hideBackdrop\\` (default \\`false\\` for Panel) |\n| \\`allowBackgroundInteraction\\` | From the \\`allowBackgroundInteraction\\` prop |\n\n**Listening for Panel events:**\n\n\\`\\`\\`ts\nimport {\n OVERLAY_MOUNT_EVENT,\n OVERLAY_UNMOUNT_EVENT,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Panel') {\n console.log(\\\\\\`Panel opened: size=\\\\\\${e.detail.size}, anchor=\\\\\\${e.detail.anchor}\\\\\\`);\n }\n});\n\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Panel') {\n console.log(\\\\\\`Panel closed: id=\\\\\\${e.detail.id}\\\\\\`);\n }\n});\n\\`\\`\\`\n\n**Example payload (Panel, right, medium):**\n\n\\`\\`\\`json\n{\n \"id\": \"d4e5f6\",\n \"overlayType\": \"Panel\",\n \"size\": \"medium\",\n \"anchor\": \"right\",\n \"hasBackdrop\": false,\n \"tapOutsideToClose\": true,\n \"allowBackgroundInteraction\": false,\n \"testId\": \"my-panel\"\n}\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Panel/Panel',\n },\n },\n};\n\nexport const NormalStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nNormalStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-normal-story',\n};\n\nexport const WithNestedDialogStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState<boolean>(args.isOpen || false);\n const [isOpen2, setIsOpen2] = React.useState(false);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen || false);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>\n Open Panel With Nested Dialog\n </Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title(First Elevation)</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n <Dialog\n initialFocus={1}\n onClose={() => setIsOpen2(false)}\n semantic=\"neutral\"\n isOpen={isOpen2}\n >\n <DialogHeader>\n <SubTitleLarge> Dialog Title</SubTitleLarge>\n </DialogHeader>\n <DialogBody>\n <BodyLarge color=\"secondary\">\n Dialogs should only be used occasionally because they are\n intended to be disruptive. Dialogs come in multiple variants.\n </BodyLarge>\n </DialogBody>\n <DialogFooter>\n <Button isFluid onClick={() => setIsOpen2(false)} type=\"tertiary\">\n Close\n </Button>\n <Button\n isFluid\n onClick={() => setIsOpen2(false)}\n type=\"secondary\"\n >\n Confirm\n </Button>\n </DialogFooter>\n </Dialog>\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen2(true)}>\n Open Nested Dialog\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithNestedDialogStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-with-nested-dialog-story',\n};\n\nexport const WithInteractiveBackgroundStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <div className={css.interactionContainer}>\n <Tooltip\n body=\"When the panel opens, the background content is interactive\"\n bodyMaxLines={2}\n placement=\"top\"\n title=\"I am interactive tooltip\"\n >\n <Button iconLeftName=\"face-sunglasses\" type=\"tertiary\">\n Hover Me after opening the panel\n </Button>\n </Tooltip>\n </div>\n\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithInteractiveBackgroundStory.args = {\n anchor: 'right',\n size: 'medium',\n initialFocus: 1,\n allowBackgroundInteraction: true,\n testId: 'panel-with-interactive-background-story',\n};\nNormalStory.storyName = 'Normal';\nWithNestedDialogStory.storyName = 'With Nested Dialog';\nWithInteractiveBackgroundStory.storyName = 'With Interactive Background';\n"
|
|
1802
|
+
"content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport {\n Dialog,\n DialogBody,\n DialogFooter,\n DialogHeader,\n} from 'src/components/Dialog';\nimport {SimpleDropdown} from 'src/components/Dropdown';\nimport {Input} from 'src/components/Input';\nimport type {PanelProps} from 'src/components/Panel/Panel';\nimport {\n Panel,\n PanelBody,\n PanelFooter,\n PanelHeader,\n} from 'src/components/Panel/Panel';\nimport {BodyLarge, SubTitleLarge} from 'src/components/Text';\nimport {Textarea} from 'src/components/Textarea';\nimport {Tooltip} from 'src/components/Tooltip';\n\nimport css from 'src/components/Panel/Panel.stories.module.css';\n\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Panel',\n argTypes: {\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n anchor: {\n options: ['left', 'right'],\n description: 'Position of Panel',\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'left'},\n },\n },\n allowBackgroundInteraction: {\n description:\n 'if **true**, allows interaction with the background content. This would remove the backdrop layer for the panel and set tapOutsideToClose to false',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n size: {\n description:\n 'Panel supports only three size variants namely small, medium and large. `small` < `medium` < `large`',\n options: ['small', 'medium', 'large'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'medium'},\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n customAnimation: {\n description: `\n\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n\\`customAnimation: UseTransitionStylesProps\\` prop for\nall your custom animation needs.\nIt defines the following properties:\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed.\n\nThis is the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Panel component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Panel, PanelBody, PanelHeader, PanelFooter } from \"@spaced-out/ui-design-system/lib/components/Panel\";\n\\`\\`\\`\nDestinations in the app are accessible through Panels. Panels are **side sheets**, which are attached to the left or\nright edge of the screen and are surfaces with extra content. Panels can either be permanently on-screen or controlled by an **action**.\n\nPanel is a variation of a **<a href=\"../?path=/docs/components-modal--docs\">Modal</a>** with additional animation, position and size overrides.\n\nSemantically a Panel component should be composed from \\`PanelHeader\\`, \\`PanelBody\\`, and \\`PanelFooter\\` **components**, these are nothing but layout components which defines\nappropriate spacing for the children living in them. \\`PanelHeader\\` adds a close icon by default and provides a callback on click. You can pass a prop to\nshow/hide the close button as well.\nEach of these components also exposes a className\n\n---\n\n### Overlay Lifecycle Events\n\nPanel emits **strongly-typed window events** when it mounts and unmounts (see **<a href=\"../?path=/docs/components-modal--docs\">Modal docs</a>** for the full API reference, all event types, and advanced usage patterns).\n\nPanel-specific fields in the event payload:\n\n| Field | Value |\n|---|---|\n| \\`overlayType\\` | \\`'Panel'\\` |\n| \\`size\\` | \\`'small' \\\\| 'medium' \\\\| 'large'\\` (from the \\`size\\` prop) |\n| \\`anchor\\` | \\`'left' \\\\| 'right'\\` (from the \\`anchor\\` prop) |\n| \\`hasBackdrop\\` | Derived from \\`hideBackdrop\\` (default \\`false\\` for Panel) |\n| \\`allowBackgroundInteraction\\` | From the \\`allowBackgroundInteraction\\` prop |\n\n**Listening for Panel events:**\n\n\\`\\`\\`ts\nimport {\n OVERLAY_MOUNT_EVENT,\n OVERLAY_UNMOUNT_EVENT,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Panel') {\n console.log(\\\\\\`Panel opened: size=\\\\\\${e.detail.size}, anchor=\\\\\\${e.detail.anchor}\\\\\\`);\n }\n});\n\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Panel') {\n console.log(\\\\\\`Panel closed: id=\\\\\\${e.detail.id}\\\\\\`);\n }\n});\n\\`\\`\\`\n\n**Example payload (Panel, right, medium):**\n\n\\`\\`\\`json\n{\n \"id\": \"d4e5f6\",\n \"overlayType\": \"Panel\",\n \"size\": \"medium\",\n \"anchor\": \"right\",\n \"hasBackdrop\": false,\n \"tapOutsideToClose\": true,\n \"allowBackgroundInteraction\": false,\n \"testId\": \"my-panel\"\n}\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Panel/Panel',\n },\n },\n};\n\nexport const NormalStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nNormalStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-normal-story',\n};\n\nexport const WithNestedDialogStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState<boolean>(args.isOpen || false);\n const [isOpen2, setIsOpen2] = React.useState(false);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen || false);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>\n Open Panel With Nested Dialog\n </Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title(First Elevation)</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n <Dialog\n initialFocus={1}\n onClose={() => setIsOpen2(false)}\n semantic=\"neutral\"\n isOpen={isOpen2}\n >\n <DialogHeader>\n <SubTitleLarge> Dialog Title</SubTitleLarge>\n </DialogHeader>\n <DialogBody>\n <BodyLarge color=\"secondary\">\n Dialogs should only be used occasionally because they are\n intended to be disruptive. Dialogs come in multiple variants.\n </BodyLarge>\n </DialogBody>\n <DialogFooter>\n <Button isFluid onClick={() => setIsOpen2(false)} type=\"tertiary\">\n Close\n </Button>\n <Button\n isFluid\n onClick={() => setIsOpen2(false)}\n type=\"secondary\"\n >\n Confirm\n </Button>\n </DialogFooter>\n </Dialog>\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen2(true)}>\n Open Nested Dialog\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithNestedDialogStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-with-nested-dialog-story',\n};\n\nexport const WithInteractiveBackgroundStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <div className={css.interactionContainer}>\n <Tooltip\n body=\"When the panel opens, the background content is interactive\"\n bodyMaxLines={2}\n placement=\"top\"\n title=\"I am interactive tooltip\"\n >\n <Button iconLeftName=\"face-sunglasses\" type=\"tertiary\">\n Hover Me after opening the panel\n </Button>\n </Tooltip>\n </div>\n\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithInteractiveBackgroundStory.args = {\n anchor: 'right',\n size: 'medium',\n initialFocus: 1,\n allowBackgroundInteraction: true,\n testId: 'panel-with-interactive-background-story',\n};\n\nexport const WithHeaderSlotsStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader\n onCloseButtonClick={() => setIsOpen(false)}\n size=\"medium\"\n leftSlot={<Button iconLeftName=\"bookmark\" type=\"tertiary\" />}\n rightSlot={\n <div className={css.headerRightSlot}>\n <Button\n iconLeftName=\"circle-info\"\n type=\"ghost\"\n classNames={{wrapper: css.helpButton}}\n >\n Help\n </Button>\n </div>\n }\n >\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithHeaderSlotsStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-with-header-slots-story',\n};\n\nNormalStory.storyName = 'Normal';\nWithNestedDialogStory.storyName = 'With Nested Dialog';\nWithInteractiveBackgroundStory.storyName = 'With Interactive Background';\nWithHeaderSlotsStory.storyName = 'With Header Slots';\n"
|
|
1755
1803
|
},
|
|
1756
1804
|
"css": {
|
|
1757
1805
|
"path": "Panel.module.css",
|
|
1758
|
-
"content": "@value (spaceNegFluid, spaceNone, spaceMedium, spaceSmall, spaceFluid) from '../../styles/variables/_space.css';\n@value (size4, size60, size480, size580, size720, sizeFluid) from '../../styles/variables/_size.css';\n@value (motionDurationNormal, motionEaseInEaseOut) from '../../styles/variables/_motion.css';\n@value (colorBackgroundTertiary, colorBackgroundPrimary) from '../../styles/variables/_color.css';\n@value (borderRadiusNone) from '../../styles/variables/_border.css';\n\n.panel {\n opacity: initial;\n height: sizeFluid;\n background-color: colorBackgroundTertiary;\n border-radius: borderRadiusNone;\n}\n\n.small {\n width: size480;\n}\n\n.medium {\n width: size580;\n}\n\n.large {\n width: size720;\n}\n\n.panel.left {\n top: spaceNone;\n left: spaceNone;\n right: initial;\n transform: translateX(spaceNegFluid);\n}\n\n.panel.right {\n top: spaceNone;\n right: spaceNone;\n left: initial;\n transform: translateX(spaceFluid);\n}\n\n.panelContainer.open.in .left,\n.panelContainer.open.in .right {\n transform: translateX(spaceNone);\n}\n\n.panelHeader {\n composes: borderBottomPrimary from '../../styles/border.module.css';\n composes: subTitleLarge from '../../styles/typography.module.css';\n padding: spaceNone spaceSmall spaceNone spaceMedium;\n min-height: size60;\n display: flex;\n
|
|
1806
|
+
"content": "@value (spaceNegFluid, spaceNone, spaceMedium, spaceSmall, spaceFluid) from '../../styles/variables/_space.css';\n@value (size4, size60, size480, size580, size720, sizeFluid) from '../../styles/variables/_size.css';\n@value (motionDurationNormal, motionEaseInEaseOut) from '../../styles/variables/_motion.css';\n@value (colorBackgroundTertiary, colorBackgroundPrimary) from '../../styles/variables/_color.css';\n@value (borderRadiusNone) from '../../styles/variables/_border.css';\n\n.panel {\n opacity: initial;\n height: sizeFluid;\n background-color: colorBackgroundTertiary;\n border-radius: borderRadiusNone;\n}\n\n.small {\n width: size480;\n}\n\n.medium {\n width: size580;\n}\n\n.large {\n width: size720;\n}\n\n.panel.left {\n top: spaceNone;\n left: spaceNone;\n right: initial;\n transform: translateX(spaceNegFluid);\n}\n\n.panel.right {\n top: spaceNone;\n right: spaceNone;\n left: initial;\n transform: translateX(spaceFluid);\n}\n\n.panelContainer.open.in .left,\n.panelContainer.open.in .right {\n transform: translateX(spaceNone);\n}\n\n.panelHeader {\n composes: borderBottomPrimary from '../../styles/border.module.css';\n composes: subTitleLarge from '../../styles/typography.module.css';\n padding: spaceNone spaceSmall spaceNone spaceMedium;\n min-height: size60;\n display: flex;\n align-items: center;\n gap: spaceSmall;\n background-color: colorBackgroundTertiary;\n}\n\n.headerContent {\n display: flex;\n}\n\n.closeButton {\n margin-left: auto;\n}\n\n.panelBody {\n padding: spaceMedium;\n height: sizeFluid;\n overflow: auto;\n background-color: colorBackgroundPrimary;\n}\n\n.panelFooter {\n composes: borderTopPrimary from '../../styles/border.module.css';\n background-color: colorBackgroundTertiary;\n margin-top: auto;\n padding: spaceMedium;\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: spaceSmall;\n}\n\n.panelFooterActions {\n display: flex;\n gap: spaceSmall;\n}\n"
|
|
1759
1807
|
},
|
|
1760
1808
|
"index": {
|
|
1761
1809
|
"path": "index.d.ts",
|
|
@@ -1837,15 +1885,15 @@
|
|
|
1837
1885
|
"files": {
|
|
1838
1886
|
"main": {
|
|
1839
1887
|
"path": "ProgressDonut.d.ts",
|
|
1840
|
-
"content": "import type { Flow } from 'flow-to-typescript-codemod';\nimport * as COLORS from '../../styles/variables/_color';\ntype ClassNames = Readonly<{\n wrapper?: string;\n donutChart?: string;\n}>;\nexport
|
|
1888
|
+
"content": "import type { Flow } from 'flow-to-typescript-codemod';\nimport * as COLORS from '../../styles/variables/_color';\nimport type { IconProps } from '../../components/Icon';\ntype ClassNames = Readonly<{\n wrapper?: string;\n donutChart?: string;\n}>;\nexport type ProgressDonutProps = {\n classNames?: ClassNames;\n color?: keyof typeof COLORS;\n size?: 'small' | 'medium';\n testId?: string;\n icon?: Omit<IconProps, 'size'>;\n} & ({\n percentage?: number;\n rating?: never;\n} | {\n rating: number;\n percentage?: never;\n});\nexport declare const ProgressDonut: Flow.AbstractComponent<ProgressDonutProps, HTMLDivElement>;\nexport {};\n//# sourceMappingURL=ProgressDonut.d.ts.map"
|
|
1841
1889
|
},
|
|
1842
1890
|
"story": {
|
|
1843
1891
|
"path": "ProgressDonut.stories.tsx",
|
|
1844
|
-
"content": "import * as React from 'react';\n\nimport * as COLORS from 'src/styles/variables/_color';\n\nimport type {ProgressDonutProps} from 'src/components/ProgressDonut';\nimport {ProgressDonut} from 'src/components/ProgressDonut';\n\nimport css from 'src/components/ProgressDonut/ProgressDonut.stories.module.css';\n\n\nconst colorOptions: Array<unknown> = [\n '--',\n ...Object.keys(COLORS).filter((color) => color.startsWith('colorText')),\n];\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Progress Donut',\n component: ProgressDonut,\n argTypes: {\n classNames: {\n description:\n 'Provide an optional classNames to be applied to the wrapper, {wrapper?: string, donutChart?: string}',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{ wrapper?: string, donutChart?: string }',\n },\n },\n },\n percentage: {\n description:\n 'Represents the completion percentage of the donut progress, ranging from 0 to 100 inclusive',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: 0},\n },\n },\n color: {\n description:\n 'Pass different text color token string to show loader in different color',\n options: colorOptions,\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n parameters: {\n docs: {\n subtitle: 'Generates a ProgressDonut component.',\n description: {\n component: `\n\\`\\`\\`js\nimport { ProgressDonut } from \"@spaced-out/ui-design-system/lib/components/ProgressDonut\";\n\\`\\`\\`\nA progress indicator in the shape of a donut chart to visually represent completion percentages. This component uses configurable colors based on the percentage range, and supports an optional custom color.\n\n**Usage: **\n\\`\\`\\`\n<ProgressDonut
|
|
1892
|
+
"content": "import * as React from 'react';\n\nimport * as COLORS from 'src/styles/variables/_color';\n\nimport type {ProgressDonutProps} from 'src/components/ProgressDonut';\nimport {ProgressDonut} from 'src/components/ProgressDonut';\n\nimport css from 'src/components/ProgressDonut/ProgressDonut.stories.module.css';\n\n\nconst colorOptions: Array<unknown> = [\n '--',\n ...Object.keys(COLORS).filter((color) => color.startsWith('colorText')),\n];\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Progress Donut',\n component: ProgressDonut,\n argTypes: {\n classNames: {\n description:\n 'Provide an optional classNames to be applied to the wrapper, {wrapper?: string, donutChart?: string}',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{ wrapper?: string, donutChart?: string }',\n },\n },\n },\n percentage: {\n description:\n 'Represents the completion percentage of the donut progress, ranging from 0 to 100 inclusive. Mutually exclusive with `rating`.',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: 0},\n },\n },\n rating: {\n description:\n 'Represents a rating from 0 to 10. The donut fill reflects the rating proportionally, and the rating value is displayed inside instead of a percentage. Mutually exclusive with `percentage`.',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n },\n },\n size: {\n description:\n 'Size variant of the donut. `medium` renders at 72x72, `small` renders at 34x34.',\n options: ['small', 'medium'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: '\\'small\\' | \\'medium\\''},\n defaultValue: {summary: 'medium'},\n },\n },\n color: {\n description:\n 'Pass different text color token string to show loader in different color',\n options: colorOptions,\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n icon: {\n description:\n 'Optional icon to render in the center of the donut in place of the percentage/rating text. Accepts all `IconProps` except `size`, which is derived from the donut `size` (donut `small` → icon `small`, donut `medium` → icon `large`).',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: 'Omit<IconProps, \\'size\\'>',\n },\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n parameters: {\n docs: {\n subtitle: 'Generates a ProgressDonut component.',\n description: {\n component: `\n\\`\\`\\`js\nimport { ProgressDonut } from \"@spaced-out/ui-design-system/lib/components/ProgressDonut\";\n\\`\\`\\`\nA progress indicator in the shape of a donut chart to visually represent completion percentages or ratings. This component uses configurable colors based on the percentage range, and supports an optional custom color. When an \\`icon\\` is provided, it replaces the percentage/rating text in the center.\n\n**Usage: **\n\\`\\`\\`\n// Percentage mode (default)\n<ProgressDonut percentage={75} />\n\n// Rating mode (0-10 scale)\n<ProgressDonut rating={6} size=\"small\" />\n\n// Icon in the center (replaces percentage/rating text)\n<ProgressDonut\n percentage={80}\n icon={{name: 'check', type: 'solid', color: 'success'}}\n/>\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/ProgressDonut/ProgressDonut',\n },\n },\n};\n\nexport const DefaultStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nDefaultStory.args = {\n percentage: 90,\n testId: 'progress-donut-default-story',\n};\n\nexport const WithCustomColorStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nWithCustomColorStory.args = {\n percentage: 47,\n color: 'colorTextInformation',\n testId: 'progress-donut-custom-color-story',\n};\nexport const SmallSizeStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nSmallSizeStory.args = {\n percentage: 75,\n size: 'small',\n testId: 'progress-donut-small-size-story',\n};\n\nexport const RatingStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nRatingStory.args = {\n rating: 6,\n testId: 'progress-donut-rating-story',\n};\n\nexport const SmallRatingStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nSmallRatingStory.args = {\n rating: 6,\n size: 'small',\n testId: 'progress-donut-small-rating-story',\n};\n\nexport const WithIconStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nWithIconStory.args = {\n percentage: 80,\n icon: {name: 'check', type: 'solid', color: 'success'},\n testId: 'progress-donut-with-icon-story',\n};\n\nexport const SmallWithIconStory = (args: ProgressDonutProps) => (\n <div className={css.container}>\n <ProgressDonut {...args} />\n </div>\n);\n\nSmallWithIconStory.args = {\n rating: 6,\n size: 'small',\n icon: {name: 'star', type: 'solid'},\n testId: 'progress-donut-small-with-icon-story',\n};\n\nDefaultStory.storyName = 'Default';\nWithCustomColorStory.storyName = 'With Custom Color';\nSmallSizeStory.storyName = 'Small Size';\nRatingStory.storyName = 'Rating';\nSmallRatingStory.storyName = 'Small Rating';\nWithIconStory.storyName = 'With Icon';\nSmallWithIconStory.storyName = 'Small With Icon';\n"
|
|
1845
1893
|
},
|
|
1846
1894
|
"css": {
|
|
1847
1895
|
"path": "ProgressDonut.module.css",
|
|
1848
|
-
"content": "@value (\n borderRadiusSmall\n) from '../../styles/variables/_border.css';\n@value (spaceHalfFluid, spaceNegHalfFluid) from '../../styles/variables/_space.css';\n@value (size10, size20, sizeFluid) from\n '../../styles/variables/_size.css';\n@value (\n colorBorderPrimary,\n colorBackgroundSecondary,\n colorBackgroundPrimary\n) from '../../styles/variables/_color.css';\n@value (motionDurationSlower) from\n'../../styles/variables/_motion.css';\n\n.donutChart {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n background-color: colorBackgroundPrimary;\n}\n\n.donutChartSvg {\n transform: rotate(-90deg);\n}\n\n.donutChartBackground,\n.donutChartForeground {\n fill: none;\n}\n\n.donutChartBackground {\n stroke: colorBackgroundSecondary;\n}\n\n.donutChartForeground {\n transition: stroke-dashoffset motionDurationSlower;\n}\n\n.donutChartPercentage {\n position: absolute;\n}\n"
|
|
1896
|
+
"content": "@value (\n borderRadiusSmall\n) from '../../styles/variables/_border.css';\n@value (spaceHalfFluid, spaceNegHalfFluid) from '../../styles/variables/_space.css';\n@value (fontSize12) from '../../styles/variables/_font.css';\n@value (size10, size20, sizeFluid) from\n '../../styles/variables/_size.css';\n@value (\n colorBorderPrimary,\n colorBackgroundSecondary,\n colorBackgroundPrimary\n) from '../../styles/variables/_color.css';\n@value (motionDurationSlower) from\n'../../styles/variables/_motion.css';\n\n.donutChart {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n background-color: colorBackgroundPrimary;\n}\n\n.donutChartSvg {\n transform: rotate(-90deg);\n}\n\n.donutChartBackground,\n.donutChartForeground {\n fill: none;\n}\n\n.donutChartBackground {\n stroke: colorBackgroundSecondary;\n}\n\n.donutChartForeground {\n transition: stroke-dashoffset motionDurationSlower;\n}\n\n.donutChartPercentage {\n position: absolute;\n}\n\n.donutChartPercentageSmallPercent {\n font-size: fontSize12;\n}\n\n.donutChartIcon {\n position: absolute;\n}\n"
|
|
1849
1897
|
},
|
|
1850
1898
|
"index": {
|
|
1851
1899
|
"path": "index.d.ts",
|
|
@@ -2203,7 +2251,7 @@
|
|
|
2203
2251
|
"files": {
|
|
2204
2252
|
"main": {
|
|
2205
2253
|
"path": "SideMenuLink.d.ts",
|
|
2206
|
-
"content": "import * as React from 'react';\nimport type { Flow } from 'flow-to-typescript-codemod';\nimport type { BaseLinkProps } from '../../components/Link';\nimport type { StatusSemanticType } from '../../components/StatusIndicator';\nimport type { BaseTooltipProps } from '../../components/Tooltip';\nexport declare const MENU_NAME_LIST: Readonly<{\n dashboard: {\n title: string;\n iconName: string;\n iconType: string;\n };\n engage: {\n title: string;\n iconName: string;\n iconType: string;\n };\n journeys: {\n title: string;\n iconName: string;\n iconType: string;\n };\n automation: {\n title: string;\n iconName: string;\n iconType: string;\n };\n trm: {\n title: string;\n iconName: string;\n iconType: string;\n };\n analytics: {\n title: string;\n iconName: string;\n iconType: string;\n };\n messaging: {\n title: string;\n iconName: string;\n iconType: string;\n };\n messages: {\n title: string;\n iconName: string;\n iconType: string;\n };\n chatbot: {\n title: string;\n iconName: string;\n iconType: string;\n };\n referral: {\n title: string;\n iconName: string;\n iconType: string;\n };\n referrals: {\n title: string;\n iconName: string;\n iconType: string;\n };\n records: {\n title: string;\n iconName: string;\n iconType: string;\n };\n 'database-cleanup': {\n title: string;\n iconName: string;\n iconType: string;\n };\n support: {\n title: string;\n iconName: string;\n iconType: string;\n };\n audit: {\n title: string;\n iconName: string;\n iconType: string;\n };\n schedule: {\n title: string;\n iconName: string;\n iconType: string;\n };\n people: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts: {\n title: string;\n iconName: string;\n iconType: string;\n };\n meetings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts3: {\n title: string;\n iconName: string;\n iconType: string;\n };\n senseai: {\n title: string;\n iconName: string;\n iconType: string;\n };\n 'sense-jd-ai': {\n title: string;\n iconName: string;\n iconType: string;\n };\n tracking: {\n title: string;\n iconName: string;\n iconType: string;\n };\n jobs: {\n title: string;\n iconName: string;\n iconType: string;\n };\n drive: {\n title: string;\n iconName: string;\n iconType: string;\n };\n conversations: {\n title: string;\n iconName: string;\n iconType: string;\n };\n pages: {\n title: string;\n iconName: string;\n iconType: string;\n };\n sourcing: {\n title: string;\n iconName: string;\n iconType: string;\n };\n earnings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n settings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n configuration: {\n title: string;\n iconName: string;\n iconType: string;\n };\n supportLinks: {\n title: string;\n iconName: string;\n iconType: string;\n };\n voiceflow: {\n title: string;\n iconName: string;\n iconType: string;\n };\n broadcast: {\n title: string;\n iconName: string;\n iconType: string;\n };\n liveAgentTransfer: {\n title: string;\n iconName: string;\n iconType: string;\n };\n dataManagement: {\n title: string;\n iconName: string;\n iconType: string;\n };\n}>;\ntype ClassNames = Readonly<{\n wrapper?: string;\n}>;\nexport interface SideMenuLinkProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n customTitle?: string;\n pageNameKey: string;\n disabled?: boolean;\n hovered?: boolean;\n selectedValue?: string;\n opened?: boolean;\n onChange?: (e: React.SyntheticEvent<HTMLElement>, newValue: string) => unknown;\n tabIndex?: number;\n tooltip?: BaseTooltipProps;\n isGroupMenuLink?: boolean;\n to?: string;\n rightSlot?: React.ReactNode;\n linkComponent?: Flow.AbstractComponent<BaseLinkProps, HTMLAnchorElement | null | undefined>;\n status?: StatusSemanticType;\n testId?: string;\n}\nexport declare const SideMenuLink: Flow.AbstractComponent<SideMenuLinkProps, HTMLButtonElement>;\nexport {};\n//# sourceMappingURL=SideMenuLink.d.ts.map"
|
|
2254
|
+
"content": "import * as React from 'react';\nimport type { Flow } from 'flow-to-typescript-codemod';\nimport type { BaseLinkProps } from '../../components/Link';\nimport type { StatusSemanticType } from '../../components/StatusIndicator';\nimport type { BaseTooltipProps } from '../../components/Tooltip';\nexport declare const MENU_NAME_LIST: Readonly<{\n dashboard: {\n title: string;\n iconName: string;\n iconType: string;\n };\n tasks: {\n title: string;\n iconName: string;\n iconType: string;\n };\n engage: {\n title: string;\n iconName: string;\n iconType: string;\n };\n journeys: {\n title: string;\n iconName: string;\n iconType: string;\n };\n automation: {\n title: string;\n iconName: string;\n iconType: string;\n };\n trm: {\n title: string;\n iconName: string;\n iconType: string;\n };\n analytics: {\n title: string;\n iconName: string;\n iconType: string;\n };\n messaging: {\n title: string;\n iconName: string;\n iconType: string;\n };\n messages: {\n title: string;\n iconName: string;\n iconType: string;\n };\n chatbot: {\n title: string;\n iconName: string;\n iconType: string;\n };\n referral: {\n title: string;\n iconName: string;\n iconType: string;\n };\n referrals: {\n title: string;\n iconName: string;\n iconType: string;\n };\n records: {\n title: string;\n iconName: string;\n iconType: string;\n };\n 'database-cleanup': {\n title: string;\n iconName: string;\n iconType: string;\n };\n support: {\n title: string;\n iconName: string;\n iconType: string;\n };\n audit: {\n title: string;\n iconName: string;\n iconType: string;\n };\n schedule: {\n title: string;\n iconName: string;\n iconType: string;\n };\n people: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts: {\n title: string;\n iconName: string;\n iconType: string;\n };\n meetings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n contacts3: {\n title: string;\n iconName: string;\n iconType: string;\n };\n senseai: {\n title: string;\n iconName: string;\n iconType: string;\n };\n 'sense-jd-ai': {\n title: string;\n iconName: string;\n iconType: string;\n };\n tracking: {\n title: string;\n iconName: string;\n iconType: string;\n };\n jobs: {\n title: string;\n iconName: string;\n iconType: string;\n };\n drive: {\n title: string;\n iconName: string;\n iconType: string;\n };\n conversations: {\n title: string;\n iconName: string;\n iconType: string;\n };\n pages: {\n title: string;\n iconName: string;\n iconType: string;\n };\n sourcing: {\n title: string;\n iconName: string;\n iconType: string;\n };\n earnings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n settings: {\n title: string;\n iconName: string;\n iconType: string;\n };\n configuration: {\n title: string;\n iconName: string;\n iconType: string;\n };\n supportLinks: {\n title: string;\n iconName: string;\n iconType: string;\n };\n voiceflow: {\n title: string;\n iconName: string;\n iconType: string;\n };\n broadcast: {\n title: string;\n iconName: string;\n iconType: string;\n };\n liveAgentTransfer: {\n title: string;\n iconName: string;\n iconType: string;\n };\n dataManagement: {\n title: string;\n iconName: string;\n iconType: string;\n };\n notifications: {\n title: string;\n iconName: string;\n iconType: string;\n };\n}>;\ntype ClassNames = Readonly<{\n wrapper?: string;\n}>;\nexport interface SideMenuLinkProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n customTitle?: string;\n pageNameKey: string;\n disabled?: boolean;\n hovered?: boolean;\n selectedValue?: string;\n opened?: boolean;\n onChange?: (e: React.SyntheticEvent<HTMLElement>, newValue: string) => unknown;\n tabIndex?: number;\n tooltip?: BaseTooltipProps;\n isGroupMenuLink?: boolean;\n to?: string;\n rightSlot?: React.ReactNode;\n linkComponent?: Flow.AbstractComponent<BaseLinkProps, HTMLAnchorElement | null | undefined>;\n status?: StatusSemanticType;\n testId?: string;\n}\nexport declare const SideMenuLink: Flow.AbstractComponent<SideMenuLinkProps, HTMLButtonElement>;\nexport {};\n//# sourceMappingURL=SideMenuLink.d.ts.map"
|
|
2207
2255
|
},
|
|
2208
2256
|
"story": {
|
|
2209
2257
|
"path": "SideMenuLink.stories.tsx",
|
|
@@ -2440,7 +2488,7 @@
|
|
|
2440
2488
|
"story": null,
|
|
2441
2489
|
"css": {
|
|
2442
2490
|
"path": "Table.module.css",
|
|
2443
|
-
"content": "@value (\n colorFillPrimary,\n colorFillSecondary,\n colorTextPrimary,\n colorTextSecondary,\n colorBorderPrimary,\n colorBorderSecondary,\n colorFillSecondary,\n colorBackgroundPrimary,\n colorBackgroundTertiary,\n colorGrayLightest\n) from '../../styles/variables/_color.css';\n@value (\n spaceNone, \n spaceXXSmall, \n spaceXSmall,\n spaceSmall, \n spaceMedium\n) from '../../styles/variables/_space.css';\n@value (\n sizeFluid, \n size2, \n size8, \n size48, \n size60, \n size240, \n size300\n) from '../../styles/variables/_size.css';\n@value (\n borderWidthNone, \n borderWidthPrimary, \n borderRadiusNone, \n borderRadiusMedium, \n borderWidthSecondary\n) from '../../styles/variables/_border.css';\n@value (\n fontLineHeight170\n) from '../../styles/variables/_font.css';\n@value (\n elevationCard\n) from '../../styles/variables/_elevation.css';\n\n@value tableRowTotalPadding: calc(spaceMedium * 2);\n\n.fooBar {\n color: colorFillPrimary;\n}\n\n.tableContainer {\n --border-radius: borderRadiusMedium;\n --table-width: sizeFluid;\n height: var(--table-height);\n composes: borderPrimary from '../../styles/border.module.css';\n width: sizeFluid;\n overflow-x: auto;\n border-radius: var(--border-radius);\n}\n\n.defaultTable {\n min-width: sizeFluid;\n height: fit-content;\n flex-flow: column;\n overflow-x: auto;\n border-collapse: collapse;\n box-sizing: border-box;\n border-radius: var(--border-radius);\n box-shadow: borderWidthNone borderWidthNone borderWidthNone borderWidthPrimary\n colorBorderPrimary;\n table-layout: fixed;\n white-space: nowrap;\n}\n.fullHeightTable {\n height: sizeFluid;\n}\n.defaultTableBody {\n flex-flow: column;\n border-radius: borderRadiusNone borderRadiusNone var(--border-radius)\n var(--border-radius);\n background: colorBackgroundTertiary;\n}\n\n.defaultSelectedBodyRow {\n background: colorFillSecondary;\n}\n\n.labelContents {\n display: flex;\n justify-content: space-between;\n flex: 1;\n}\n.labelContainer {\n align-items: center;\n}\n\n.defaultHeaderCellSortable.sorted .sortArrow {\n visibility: visible;\n}\n\n.defaultCell,\n.defaultSingleCell,\n.defaultDoubleCell {\n height: size48;\n align-items: center;\n padding: spaceNone spaceXSmall;\n background: colorBackgroundTertiary;\n}\n\n.defaultDoubleCell {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.paddedTitleBlock {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n}\n\n.defaultSingleCell {\n /*used to retain bottom border on cell if content is full-bleed */\n padding-bottom: borderWidthPrimary;\n}\n\n.defaultHeadCell {\n composes: defaultCell;\n background: colorBackgroundPrimary;\n}\n\n.defaultDoubleCell {\n height: size60;\n}\n\n.singleContentCell {\n composes: defaultCell;\n padding: spaceNone spaceXSmall;\n}\n.doubleContentCell {\n composes: defaultDoubleCell;\n padding: spaceNone spaceXSmall;\n}\n\n.doubleTitle {\n margin: spaceNone;\n}\n.doubleSubtitle {\n display: block;\n height: fontLineHeight170;\n}\n\n.stickyHeaderCell,\n.stickyCell {\n position: sticky;\n left: spaceNone;\n z-index: calc(elevationCard / 2);\n}\n\n.stickyHeaderCell::after,\n.stickyCell::after {\n content: '';\n position: absolute;\n right: calc(borderWidthPrimary * -1);\n top: spaceNone;\n width: calc(size2 / 2);\n height: sizeFluid;\n background: colorBorderSecondary;\n}\n\n.stickyHeaderCell {\n background: colorBackgroundPrimary;\n}\n\n/**\n Row CSS\n*/\n\n.defaultRow {\n composes: borderBottomPrimary from '../../styles/border.module.css';\n height: size48;\n background: colorBackgroundTertiary;\n}\n\n.defaultTable .defaultRow:last-child td:first-child {\n border-bottom-left-radius: var(--border-radius);\n}\n\n.defaultTable .defaultRow:last-child td:last-child {\n border-bottom-right-radius: var(--border-radius);\n}\n\n.defaultTable .defaultRow:last-child {\n border-bottom: none;\n}\n\n.emptyRow {\n display: flex;\n width: calc(var(--table-width) - tableRowTotalPadding);\n position: sticky;\n left: spaceMedium;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n}\n\n.defaultLoader {\n display: flex;\n align-items: center;\n justify-content: center;\n height: size240;\n}\n\n.defaultEmptyText {\n display: flex;\n align-items: center;\n justify-content: center;\n height: size240;\n}\n\n.checkbox {\n padding: spaceSmall spaceMedium spaceSmall spaceNone;\n max-width: size60;\n}\n\n.defaultTable td:first-child {\n padding-left: spaceMedium;\n}\n\n.defaultTable th:first-child {\n padding-left: spaceMedium;\n}\n\n/* Header CSS */\n\n.defaultTableHead {\n flex-flow: column;\n border-radius: var(--border-radius) var(--border-radius) borderRadiusNone\n borderRadiusNone;\n composes: borderBottomPrimary from '../../styles/border.module.css';\n padding: spaceSmall;\n}\n\n.defaultHeaderRow {\n box-sizing: border-box;\n background: colorBackgroundPrimary;\n border-radius: var(--border-radius) var(--border-radius) borderRadiusNone\n borderRadiusNone;\n}\n\n.labelContents {\n display: flex;\n justify-content: flex-start;\n flex: 1;\n flex-direction: row;\n align-items: flex-start;\n padding: spaceNone;\n gap: spaceXXSmall;\n}\n\n.labelContainer {\n align-items: center;\n}\n\n.defaultHeaderCellSortable {\n cursor: pointer;\n}\n\n.defaultHeaderCell,\n.defaultHeaderCellSortable {\n padding: spaceNone spaceXSmall;\n text-align: left;\n align-items: center;\n}\n\n.defaultHeaderCell:first-child {\n border-top-left-radius: var(--border-radius);\n}\n\n.defaultHeaderCell:last-child {\n border-top-right-radius: var(--border-radius);\n}\n\n.defaultHeaderCell:not(.selectedHeader):hover {\n background: colorGrayLightest;\n}\n\n.selectedHeader {\n color: colorTextPrimary;\n background: colorFillSecondary;\n}\n\n.sortArrow {\n color: colorTextSecondary;\n}\n\n.selectedSortArrow {\n color: colorTextPrimary;\n}\n\n.stickyHeader {\n position: sticky;\n top: spaceNone;\n z-index: elevationCard;\n}\n\n.stickyHeader::after {\n content: '';\n position: absolute;\n bottom: calc(borderWidthSecondary * -1);\n left: spaceNone;\n width: sizeFluid;\n height: calc(size2 / 2);\n background: colorBorderPrimary;\n}\n\n.fetchMoreLoaderContainer {\n display: flex;\n text-align: center;\n justify-content: center;\n padding: size8;\n}\n"
|
|
2491
|
+
"content": "@value (\n colorFillPrimary,\n colorFillSecondary,\n colorTextPrimary,\n colorTextSecondary,\n colorBorderPrimary,\n colorBorderSecondary,\n colorFillSecondary,\n colorBackgroundPrimary,\n colorBackgroundTertiary,\n colorGrayLightest\n) from '../../styles/variables/_color.css';\n@value (\n spaceNone, \n spaceXXSmall, \n spaceXSmall,\n spaceSmall, \n spaceMedium\n) from '../../styles/variables/_space.css';\n@value (\n sizeFluid, \n size2, \n size8, \n size48, \n size60, \n size240, \n size300\n) from '../../styles/variables/_size.css';\n@value (\n borderWidthNone, \n borderWidthPrimary, \n borderRadiusNone, \n borderRadiusMedium, \n borderWidthSecondary\n) from '../../styles/variables/_border.css';\n@value (\n fontLineHeight170\n) from '../../styles/variables/_font.css';\n@value (\n elevationCard\n) from '../../styles/variables/_elevation.css';\n\n@value tableRowTotalPadding: calc(spaceMedium * 2);\n\n.fooBar {\n color: colorFillPrimary;\n}\n\n.tableContainer {\n --border-radius: borderRadiusMedium;\n --table-width: sizeFluid;\n height: var(--table-height);\n composes: borderPrimary from '../../styles/border.module.css';\n width: sizeFluid;\n overflow-x: auto;\n border-radius: var(--border-radius);\n}\n\n.defaultTable {\n min-width: sizeFluid;\n height: fit-content;\n flex-flow: column;\n overflow-x: auto;\n border-collapse: collapse;\n box-sizing: border-box;\n border-radius: var(--border-radius);\n box-shadow: borderWidthNone borderWidthNone borderWidthNone borderWidthPrimary\n colorBorderPrimary;\n table-layout: fixed;\n white-space: nowrap;\n}\n.fullHeightTable {\n height: sizeFluid;\n}\n.defaultTableBody {\n flex-flow: column;\n border-radius: borderRadiusNone borderRadiusNone var(--border-radius)\n var(--border-radius);\n background: colorBackgroundTertiary;\n}\n\n.defaultSelectedBodyRow {\n background: colorFillSecondary;\n}\n\n.labelContents {\n display: flex;\n justify-content: space-between;\n flex: 1;\n}\n.labelContainer {\n align-items: center;\n}\n\n.defaultHeaderCellSortable.sorted .sortArrow {\n visibility: visible;\n}\n\n.defaultCell,\n.defaultSingleCell,\n.defaultDoubleCell {\n height: size48;\n align-items: center;\n padding: spaceNone spaceXSmall;\n background: colorBackgroundTertiary;\n}\n\n.defaultDoubleCell {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.paddedTitleBlock {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n}\n\n.defaultSingleCell {\n /*used to retain bottom border on cell if content is full-bleed */\n padding-bottom: borderWidthPrimary;\n}\n\n.defaultHeadCell {\n composes: defaultCell;\n background: colorBackgroundPrimary;\n}\n\n.defaultDoubleCell {\n height: size60;\n}\n\n.singleContentCell {\n composes: defaultCell;\n padding: spaceNone spaceXSmall;\n}\n.doubleContentCell {\n composes: defaultDoubleCell;\n padding: spaceNone spaceXSmall;\n}\n\n.doubleTitle {\n margin: spaceNone;\n}\n.doubleSubtitle {\n display: block;\n height: fontLineHeight170;\n}\n\n.stickyHeaderCell,\n.stickyCell {\n position: sticky;\n left: spaceNone;\n z-index: calc(elevationCard / 2);\n}\n\n.stickyHeaderCell::after,\n.stickyCell::after {\n content: '';\n position: absolute;\n right: calc(borderWidthPrimary * -1);\n top: spaceNone;\n width: calc(size2 / 2);\n height: sizeFluid;\n background: colorBorderSecondary;\n}\n\n.stickyHeaderCell {\n background: colorBackgroundPrimary;\n}\n\n/**\n Row CSS\n*/\n\n.defaultRow {\n composes: borderBottomPrimary from '../../styles/border.module.css';\n height: size48;\n background: colorBackgroundTertiary;\n}\n\n.defaultTable .defaultRow:last-child td:first-child {\n border-bottom-left-radius: var(--border-radius);\n}\n\n.defaultTable .defaultRow:last-child td:last-child {\n border-bottom-right-radius: var(--border-radius);\n}\n\n.defaultTable .defaultRow:last-child {\n border-bottom: none;\n}\n\n.emptyRow {\n display: flex;\n width: calc(var(--table-width) - tableRowTotalPadding);\n position: sticky;\n left: spaceMedium;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n}\n\n.defaultLoader {\n display: flex;\n align-items: center;\n justify-content: center;\n height: size240;\n}\n\n.defaultEmptyText {\n display: flex;\n align-items: center;\n justify-content: center;\n height: size240;\n}\n\n.defaultHeaderCell.checkbox {\n padding: spaceSmall spaceMedium spaceSmall spaceNone;\n max-width: size60;\n}\n\n.defaultTable td:first-child {\n padding-left: spaceMedium;\n}\n\n.defaultTable th:first-child {\n padding-left: spaceMedium;\n}\n\n/* Header CSS */\n\n.defaultTableHead {\n flex-flow: column;\n border-radius: var(--border-radius) var(--border-radius) borderRadiusNone\n borderRadiusNone;\n composes: borderBottomPrimary from '../../styles/border.module.css';\n padding: spaceSmall;\n}\n\n.defaultHeaderRow {\n box-sizing: border-box;\n background: colorBackgroundPrimary;\n border-radius: var(--border-radius) var(--border-radius) borderRadiusNone\n borderRadiusNone;\n}\n\n.labelContents {\n display: flex;\n justify-content: flex-start;\n flex: 1;\n flex-direction: row;\n align-items: flex-start;\n padding: spaceNone;\n gap: spaceXXSmall;\n}\n\n.labelContainer {\n align-items: center;\n}\n\n.defaultHeaderCellSortable {\n cursor: pointer;\n}\n\n.defaultHeaderCell,\n.defaultHeaderCellSortable {\n padding: spaceNone spaceXSmall;\n text-align: left;\n align-items: center;\n}\n\n.defaultHeaderCell:first-child {\n border-top-left-radius: var(--border-radius);\n}\n\n.defaultHeaderCell:last-child {\n border-top-right-radius: var(--border-radius);\n}\n\n.defaultHeaderCell:not(.selectedHeader):hover {\n background: colorGrayLightest;\n}\n\n.selectedHeader {\n color: colorTextPrimary;\n background: colorFillSecondary;\n}\n\n.sortArrow {\n color: colorTextSecondary;\n}\n\n.selectedSortArrow {\n color: colorTextPrimary;\n}\n\n.stickyHeader {\n position: sticky;\n top: spaceNone;\n z-index: elevationCard;\n}\n\n.stickyHeader::after {\n content: '';\n position: absolute;\n bottom: calc(borderWidthSecondary * -1);\n left: spaceNone;\n width: sizeFluid;\n height: calc(size2 / 2);\n background: colorBorderPrimary;\n}\n\n.fetchMoreLoaderContainer {\n display: flex;\n text-align: center;\n justify-content: center;\n padding: size8;\n}\n"
|
|
2444
2492
|
},
|
|
2445
2493
|
"index": {
|
|
2446
2494
|
"path": "index.d.ts",
|
|
@@ -2457,7 +2505,7 @@
|
|
|
2457
2505
|
},
|
|
2458
2506
|
"DefaultTableHeader.d.ts": {
|
|
2459
2507
|
"path": "DefaultTableHeader.d.ts",
|
|
2460
|
-
"content": "import * as React from 'react';\nimport type { ClassNameComponent } from '../../utils/makeClassNameComponent';\nimport type { SortDirection } from '../../components/Table/hooks';\nimport type { GenericObject } from '../../components/Table/Table';\nexport interface GenericHeaderItem<T, U> {\n label: React.ReactNode;\n key: keyof T;\n className?: string;\n filterIcon?: React.ReactNode;\n filtered?: boolean;\n subtext?: string;\n sortable?: boolean;\n headerIconClassName?: string;\n sticky?: boolean;\n render?: React.ComponentType<{\n data: T;\n extras?: U;\n className?: string;\n selected?: boolean;\n disabled?: boolean;\n testId?: string;\n }>;\n}\nexport type GenericHeaderItems<T, U> = GenericHeaderItem<T, U>[];\nexport declare const BasicHeadCell: ClassNameComponent<'th'>;\nexport declare const BasicTableHead: ClassNameComponent<'thead'>;\nexport interface TableHeaderProps<T, U> {\n className?: string;\n tableHeaderClassName?: string;\n sortable?: boolean;\n columns: GenericHeaderItems<T, U>;\n handleSortClick?: (sortKey: keyof T) => unknown;\n sortKey?: keyof T;\n sortDirection?: SortDirection;\n checked?: 'true' | 'false' | 'mixed';\n handleCheckboxClick?: (arg1: {\n value: string;\n checked: boolean;\n }) => unknown;\n disabled?: boolean;\n stickyHeader?: boolean;\n testId?: string;\n}\nexport declare function DefaultTableHeader<T extends GenericObject, U extends GenericObject>(props: TableHeaderProps<T, U>): React.JSX.Element;\n//# sourceMappingURL=DefaultTableHeader.d.ts.map"
|
|
2508
|
+
"content": "import * as React from 'react';\nimport type { ClassNameComponent } from '../../utils/makeClassNameComponent';\nimport type { SortDirection } from '../../components/Table/hooks';\nimport type { GenericObject } from '../../components/Table/Table';\nexport interface GenericHeaderItem<T, U> {\n label: React.ReactNode;\n key: keyof T;\n className?: string;\n filterIcon?: React.ReactNode;\n filtered?: boolean;\n subtext?: string;\n sortable?: boolean;\n headerIconClassName?: string;\n sticky?: boolean;\n render?: React.ComponentType<{\n data: T;\n extras?: U;\n className?: string;\n selected?: boolean;\n disabled?: boolean;\n testId?: string;\n }>;\n}\nexport type GenericHeaderItems<T, U> = GenericHeaderItem<T, U>[];\nexport declare const BasicHeadCell: ClassNameComponent<'th'>;\nexport declare const BasicTableHead: ClassNameComponent<'thead'>;\nexport interface TableHeaderProps<T, U> {\n className?: string;\n tableHeaderClassName?: string;\n sortable?: boolean;\n columns: GenericHeaderItems<T, U>;\n handleSortClick?: (sortKey: keyof T) => unknown;\n sortKey?: keyof T;\n sortDirection?: SortDirection;\n checked?: 'true' | 'false' | 'mixed';\n handleCheckboxClick?: (arg1: {\n value: string;\n checked: boolean;\n }) => unknown;\n disabled?: boolean;\n stickyHeader?: boolean;\n checkboxClassName?: string;\n testId?: string;\n}\nexport declare function DefaultTableHeader<T extends GenericObject, U extends GenericObject>(props: TableHeaderProps<T, U>): React.JSX.Element;\n//# sourceMappingURL=DefaultTableHeader.d.ts.map"
|
|
2461
2509
|
},
|
|
2462
2510
|
"StaticTable.d.ts": {
|
|
2463
2511
|
"path": "StaticTable.d.ts",
|
|
@@ -2978,7 +3026,7 @@
|
|
|
2978
3026
|
},
|
|
2979
3027
|
"VoiceOrb/VoiceOrb.d.ts": {
|
|
2980
3028
|
"path": "VoiceOrb/VoiceOrb.d.ts",
|
|
2981
|
-
"content": "import * as React from 'react';\ntype ClassNames = Readonly<{\n container?: string;\n orbContainer?: string;\n orb?: string;\n}>;\nexport interface VoiceOrbProps {\n classNames?: ClassNames;\n /** Enable listening to microphone audio input for bar animation */\n enableMicrophone?: boolean;\n
|
|
3029
|
+
"content": "import * as React from 'react';\ntype ClassNames = Readonly<{\n container?: string;\n orbContainer?: string;\n orb?: string;\n}>;\nexport interface VoiceOrbHandle {\n setVolume: (volume: number) => void;\n}\nexport interface VoiceOrbProps {\n classNames?: ClassNames;\n /** Enable listening to microphone audio input for bar animation */\n enableMicrophone?: boolean;\n testId?: string;\n loading?: boolean;\n}\nexport declare const VoiceOrb: React.ForwardRefExoticComponent<VoiceOrbProps & React.RefAttributes<VoiceOrbHandle>>;\nexport {};\n//# sourceMappingURL=VoiceOrb.d.ts.map"
|
|
2982
3030
|
},
|
|
2983
3031
|
"VoiceOrb/index.d.ts": {
|
|
2984
3032
|
"path": "VoiceOrb/index.d.ts",
|
|
@@ -2986,7 +3034,7 @@
|
|
|
2986
3034
|
},
|
|
2987
3035
|
"constants.d.ts": {
|
|
2988
3036
|
"path": "constants.d.ts",
|
|
2989
|
-
"content": "export declare const BAR_COUNT = 5;\nexport declare const BASE_HEIGHT = 4;\nexport declare const MAX_MULTIPLIERS: readonly [4, 8, 12, 8, 4];\nexport declare const MIN_SHADOW_BLUR = 0;\nexport declare const MAX_SHADOW_BLUR = 30;\nexport declare const MIN_SHADOW_BLUR_2 = 0;\nexport declare const MAX_SHADOW_BLUR_2 = 50;\nexport declare const MIN_SHADOW_BLUR_3 = 0;\nexport declare const MAX_SHADOW_BLUR_3 = 70;\nexport declare const MIN_OPACITY_1 = 0.3;\nexport declare const MAX_OPACITY_1 = 0.8;\nexport declare const MIN_OPACITY_2 = 0.2;\nexport declare const MAX_OPACITY_2 = 0.6;\nexport declare const MIN_OPACITY_3 = 0.15;\nexport declare const MAX_OPACITY_3 = 0.4;\nexport declare function calculateOrbShadowVars(volume: number):
|
|
3037
|
+
"content": "export declare const BAR_COUNT = 5;\nexport declare const BASE_HEIGHT = 4;\nexport declare const MAX_MULTIPLIERS: readonly [4, 8, 12, 8, 4];\nexport declare const MIN_SHADOW_BLUR = 0;\nexport declare const MAX_SHADOW_BLUR = 30;\nexport declare const MIN_SHADOW_BLUR_2 = 0;\nexport declare const MAX_SHADOW_BLUR_2 = 50;\nexport declare const MIN_SHADOW_BLUR_3 = 0;\nexport declare const MAX_SHADOW_BLUR_3 = 70;\nexport declare const MIN_OPACITY_1 = 0.3;\nexport declare const MAX_OPACITY_1 = 0.8;\nexport declare const MIN_OPACITY_2 = 0.2;\nexport declare const MAX_OPACITY_2 = 0.6;\nexport declare const MIN_OPACITY_3 = 0.15;\nexport declare const MAX_OPACITY_3 = 0.4;\nexport declare function calculateOrbShadowVars(volume: number): Record<string, string>;\nexport declare function uuid(): string;\n//# sourceMappingURL=constants.d.ts.map"
|
|
2990
3038
|
}
|
|
2991
3039
|
}
|
|
2992
3040
|
},
|
|
@@ -3068,11 +3116,11 @@
|
|
|
3068
3116
|
"files": {
|
|
3069
3117
|
"main": {
|
|
3070
3118
|
"path": "useAudioAnalyzer.d.ts",
|
|
3071
|
-
"content": "export interface AudioAnalyzerOptions {\n /** Enable/disable audio analysis */\n isListening: boolean;\n /** Optional external MediaStream to use */\n audioStream?: MediaStream | null;\n /** Number of bars to generate intensity values for */\n barCount?: number;\n /** Smoothing factor for the analyzer (0-1) */\n smoothingTimeConstant?: number;\n /** FFT size for frequency analysis */\n fftSize?: number;\n /** Minimum ms between state updates (throttle). Default 50 (~20fps). */\n updateIntervalMs?: number;\n}\nexport interface AudioAnalyzerResult {\n /**
|
|
3119
|
+
"content": "export interface AudioAnalyzerOptions {\n /** Enable/disable audio analysis */\n isListening: boolean;\n /** Optional external MediaStream to use */\n audioStream?: MediaStream | null;\n /** Number of bars to generate intensity values for */\n barCount?: number;\n /** Smoothing factor for the analyzer (0-1) */\n smoothingTimeConstant?: number;\n /** FFT size for frequency analysis */\n fftSize?: number;\n /** Called on every rAF tick with computed intensities -- can use for imperative DOM updates */\n onAnalyze?: (intensities: number[]) => void;\n /** Minimum ms between state updates (throttle). Default 50 (~20fps). */\n updateIntervalMs?: number;\n}\nexport interface AudioAnalyzerResult {\n /** Whether the audio stream is active */\n isActive: boolean;\n /** Any error that occurred */\n error: Error | null;\n}\nexport declare const useAudioAnalyzer: {\n (options: AudioAnalyzerOptions): AudioAnalyzerResult;\n displayName: string;\n};\n//# sourceMappingURL=useAudioAnalyzer.d.ts.map"
|
|
3072
3120
|
},
|
|
3073
3121
|
"story": {
|
|
3074
3122
|
"path": "useAudioAnalyzer.stories.tsx",
|
|
3075
|
-
"content": "import * as React from 'react';\n\nimport type {MicrophoneProps} from 'src/components/VoiceOrb/Microphone/Microphone';\nimport {Microphone} from 'src/components/VoiceOrb/Microphone/Microphone';\n\nimport css from 'src/hooks/useAudioAnalyzer/useAudioAnalyzer.stories.module.css';\n\n\nconst meta = {\n tags: ['autodocs'],\n title: 'Hooks/useAudioAnalyzer',\n component: Microphone,\n argTypes: {\n enableMicrophone: {\n description:\n 'When **true**, activates the microphone and begins audio analysis.',\n control: {type: 'boolean'},\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description:\n 'Optional classNames to customize internal elements of the Microphone visualizer.',\n control: {type: 'object'},\n table: {\n type: {summary: '{ barsContainer?: string; bar?: string }'},\n },\n },\n testId: {\n description: 'Base test id used to generate element-specific test ids.',\n control: {type: 'text'},\n table: {\n type: {summary: 'string'},\n },\n },\n },\n parameters: {\n docs: {\n subtitle:\n 'Analyzes microphone audio input and
|
|
3123
|
+
"content": "import * as React from 'react';\n\nimport type {MicrophoneProps} from 'src/components/VoiceOrb/Microphone/Microphone';\nimport {Microphone} from 'src/components/VoiceOrb/Microphone/Microphone';\n\nimport css from 'src/hooks/useAudioAnalyzer/useAudioAnalyzer.stories.module.css';\n\n\nconst meta = {\n tags: ['autodocs'],\n title: 'Hooks/useAudioAnalyzer',\n component: Microphone,\n argTypes: {\n enableMicrophone: {\n description:\n 'When **true**, activates the microphone and begins audio analysis.',\n control: {type: 'boolean'},\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description:\n 'Optional classNames to customize internal elements of the Microphone visualizer.',\n control: {type: 'object'},\n table: {\n type: {summary: '{ barsContainer?: string; bar?: string }'},\n },\n },\n testId: {\n description: 'Base test id used to generate element-specific test ids.',\n control: {type: 'text'},\n table: {\n type: {summary: 'string'},\n },\n },\n },\n parameters: {\n docs: {\n subtitle:\n 'Analyzes microphone audio input and delivers intensity values via callback.',\n description: {\n component: `\n\\`\\`\\`js\nimport { useAudioAnalyzer } from \"@spaced-out/ui-design-system/lib/hooks/useAudioAnalyzer\";\n\\`\\`\\`\nA hook that captures microphone audio (or accepts an external \\`MediaStream\\`), runs FFT frequency analysis,\nand delivers normalised intensity values (0–1) via an \\`onAnalyze\\` callback on every animation frame.\nThe example below uses the \\`Microphone\\` component which consumes \\`useAudioAnalyzer\\` internally to render animated level bars.\\n\n__NOTE__: \nMic Permission will not work in non-secure contexts (storybook dev mode - http).\n\n### Options\n- \\`isListening\\`: Enable/disable audio analysis.\n- \\`audioStream\\` (optional): An external \\`MediaStream\\` to analyse instead of the default microphone.\n- \\`barCount\\` (optional): Number of intensity values to produce. Default \\`5\\`.\n- \\`smoothingTimeConstant\\` (optional): Smoothing factor for the analyser (0–1). Default \\`0.8\\`.\n- \\`fftSize\\` (optional): FFT size for frequency analysis. Default \\`256\\`.\n- \\`onAnalyze\\` (optional): Callback invoked on every animation frame with computed intensities — use for imperative DOM updates.\n- \\`updateIntervalMs\\` (optional): Minimum ms between \\`onAnalyze\\` invocations (throttle). Default \\`50\\` (~20 fps).\n\n### Return Value\n- \\`isActive\\`: Whether the audio stream is currently active.\n- \\`error\\`: Any error that occurred (e.g. microphone permission denied).\n\n### Usage\n\\`\\`\\`jsx\nimport { useCallback, useRef } from \"react\";\nimport { useAudioAnalyzer } from \"@spaced-out/ui-design-system/lib/hooks/useAudioAnalyzer\";\n\nconst BAR_COUNT = 5;\nconst BASE_HEIGHT = 4;\n\nconst AudioVisualizer = () => {\n const barsRef = useRef(null);\n\n const onAnalyze = useCallback((intensities) => {\n const container = barsRef.current;\n if (!container) return;\n const bars = container.children;\n for (let i = 0; i < intensities.length; i++) {\n bars[i].style.height = BASE_HEIGHT + intensities[i] * 40 + \"px\";\n }\n }, []);\n\n const { isActive, error } = useAudioAnalyzer({\n isListening: true,\n barCount: BAR_COUNT,\n onAnalyze,\n });\n\n if (error) return <span>Error: {error.message}</span>;\n\n return (\n <div ref={barsRef} style={{ display: \"flex\", alignItems: \"center\", gap: 4 }}>\n {Array.from({ length: BAR_COUNT }, (_, i) => (\n <div\n key={i}\n style={{\n width: 6,\n height: BASE_HEIGHT,\n borderRadius: 3,\n background: isActive ? \"#4f46e5\" : \"#d1d5db\",\n }}\n />\n ))}\n </div>\n );\n};\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/hooks/useAudioAnalyzer/useAudioAnalyzer.tsx',\n },\n },\n};\n\nexport default meta;\n\nexport const _useAudioAnalyzer = {\n render: (args: MicrophoneProps) => (\n <div className={css.container}>\n <Microphone {...args} />\n </div>\n ),\n args: {\n enableMicrophone: true,\n classNames: {},\n testId: 'use-audio-analyzer',\n },\n};\n"
|
|
3076
3124
|
},
|
|
3077
3125
|
"index": {
|
|
3078
3126
|
"path": "index.d.ts",
|
package/package.json
CHANGED