@stack-spot/citric-react 0.1.0
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/dist/citric.css +2580 -0
- package/dist/components/Accordion.d.ts +33 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +19 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Alert.d.ts +11 -0
- package/dist/components/Alert.d.ts.map +1 -0
- package/dist/components/Alert.js +5 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AsyncContent.d.ts +30 -0
- package/dist/components/AsyncContent.d.ts.map +1 -0
- package/dist/components/AsyncContent.js +33 -0
- package/dist/components/AsyncContent.js.map +1 -0
- package/dist/components/Avatar.d.ts +22 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar.js +9 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/AvatarGroup.d.ts +25 -0
- package/dist/components/AvatarGroup.d.ts.map +1 -0
- package/dist/components/AvatarGroup.js +9 -0
- package/dist/components/AvatarGroup.js.map +1 -0
- package/dist/components/Badge.d.ts +18 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +7 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Blockquote.d.ts +5 -0
- package/dist/components/Blockquote.d.ts.map +1 -0
- package/dist/components/Blockquote.js +4 -0
- package/dist/components/Blockquote.js.map +1 -0
- package/dist/components/Breadcrumb.d.ts +12 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb.js +8 -0
- package/dist/components/Breadcrumb.js.map +1 -0
- package/dist/components/Button.d.ts +42 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +25 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Card.d.ts +19 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Card.js +5 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/Checkbox.d.ts +14 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +7 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/CheckboxGroup.d.ts +53 -0
- package/dist/components/CheckboxGroup.d.ts.map +1 -0
- package/dist/components/CheckboxGroup.js +17 -0
- package/dist/components/CheckboxGroup.js.map +1 -0
- package/dist/components/Circle.d.ts +18 -0
- package/dist/components/Circle.d.ts.map +1 -0
- package/dist/components/Circle.js +5 -0
- package/dist/components/Circle.js.map +1 -0
- package/dist/components/CitricComponent.d.ts +14 -0
- package/dist/components/CitricComponent.d.ts.map +1 -0
- package/dist/components/CitricComponent.js +15 -0
- package/dist/components/CitricComponent.js.map +1 -0
- package/dist/components/Divider.d.ts +14 -0
- package/dist/components/Divider.d.ts.map +1 -0
- package/dist/components/Divider.js +5 -0
- package/dist/components/Divider.js.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +32 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +46 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/ErrorMessage.d.ts +4 -0
- package/dist/components/ErrorMessage.d.ts.map +1 -0
- package/dist/components/ErrorMessage.js +7 -0
- package/dist/components/ErrorMessage.js.map +1 -0
- package/dist/components/FallbackBoundary.d.ts +13 -0
- package/dist/components/FallbackBoundary.d.ts.map +1 -0
- package/dist/components/FallbackBoundary.js +11 -0
- package/dist/components/FallbackBoundary.js.map +1 -0
- package/dist/components/Favorite.d.ts +23 -0
- package/dist/components/Favorite.d.ts.map +1 -0
- package/dist/components/Favorite.js +5 -0
- package/dist/components/Favorite.js.map +1 -0
- package/dist/components/FieldGroup.d.ts +14 -0
- package/dist/components/FieldGroup.d.ts.map +1 -0
- package/dist/components/FieldGroup.js +5 -0
- package/dist/components/FieldGroup.js.map +1 -0
- package/dist/components/Form.d.ts +5 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Form.js +6 -0
- package/dist/components/Form.js.map +1 -0
- package/dist/components/FormGroup.d.ts +22 -0
- package/dist/components/FormGroup.d.ts.map +1 -0
- package/dist/components/FormGroup.js +8 -0
- package/dist/components/FormGroup.js.map +1 -0
- package/dist/components/IconBox.d.ts +46 -0
- package/dist/components/IconBox.d.ts.map +1 -0
- package/dist/components/IconBox.js +29 -0
- package/dist/components/IconBox.js.map +1 -0
- package/dist/components/Input.d.ts +15 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +18 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/Link.d.ts +20 -0
- package/dist/components/Link.d.ts.map +1 -0
- package/dist/components/Link.js +21 -0
- package/dist/components/Link.js.map +1 -0
- package/dist/components/LoadingPanel.d.ts +2 -0
- package/dist/components/LoadingPanel.d.ts.map +1 -0
- package/dist/components/LoadingPanel.js +5 -0
- package/dist/components/LoadingPanel.js.map +1 -0
- package/dist/components/MenuOverlay/Menu.d.ts +6 -0
- package/dist/components/MenuOverlay/Menu.d.ts.map +1 -0
- package/dist/components/MenuOverlay/Menu.js +100 -0
- package/dist/components/MenuOverlay/Menu.js.map +1 -0
- package/dist/components/MenuOverlay/context.d.ts +6 -0
- package/dist/components/MenuOverlay/context.d.ts.map +1 -0
- package/dist/components/MenuOverlay/context.js +16 -0
- package/dist/components/MenuOverlay/context.js.map +1 -0
- package/dist/components/MenuOverlay/index.d.ts +3 -0
- package/dist/components/MenuOverlay/index.d.ts.map +1 -0
- package/dist/components/MenuOverlay/index.js +23 -0
- package/dist/components/MenuOverlay/index.js.map +1 -0
- package/dist/components/MenuOverlay/keyboard.d.ts +2 -0
- package/dist/components/MenuOverlay/keyboard.d.ts.map +1 -0
- package/dist/components/MenuOverlay/keyboard.js +66 -0
- package/dist/components/MenuOverlay/keyboard.js.map +1 -0
- package/dist/components/MenuOverlay/types.d.ts +166 -0
- package/dist/components/MenuOverlay/types.d.ts.map +1 -0
- package/dist/components/MenuOverlay/types.js +2 -0
- package/dist/components/MenuOverlay/types.js.map +1 -0
- package/dist/components/Overlay/context.d.ts +4 -0
- package/dist/components/Overlay/context.d.ts.map +1 -0
- package/dist/components/Overlay/context.js +7 -0
- package/dist/components/Overlay/context.js.map +1 -0
- package/dist/components/Overlay/index.d.ts +14 -0
- package/dist/components/Overlay/index.d.ts.map +1 -0
- package/dist/components/Overlay/index.js +120 -0
- package/dist/components/Overlay/index.js.map +1 -0
- package/dist/components/Overlay/types.d.ts +67 -0
- package/dist/components/Overlay/types.d.ts.map +1 -0
- package/dist/components/Overlay/types.js +2 -0
- package/dist/components/Overlay/types.js.map +1 -0
- package/dist/components/Pagination.d.ts +28 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +30 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/ProgressBar.d.ts +12 -0
- package/dist/components/ProgressBar.d.ts.map +1 -0
- package/dist/components/ProgressBar.js +7 -0
- package/dist/components/ProgressBar.js.map +1 -0
- package/dist/components/ProgressCircular.d.ts +16 -0
- package/dist/components/ProgressCircular.d.ts.map +1 -0
- package/dist/components/ProgressCircular.js +7 -0
- package/dist/components/ProgressCircular.js.map +1 -0
- package/dist/components/RadioGroup.d.ts +48 -0
- package/dist/components/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup.js +17 -0
- package/dist/components/RadioGroup.js.map +1 -0
- package/dist/components/Rating.d.ts +13 -0
- package/dist/components/Rating.d.ts.map +1 -0
- package/dist/components/Rating.js +4 -0
- package/dist/components/Rating.js.map +1 -0
- package/dist/components/Select/RichSelect.d.ts +5 -0
- package/dist/components/Select/RichSelect.d.ts.map +1 -0
- package/dist/components/Select/RichSelect.js +152 -0
- package/dist/components/Select/RichSelect.js.map +1 -0
- package/dist/components/Select/SimpleSelect.d.ts +5 -0
- package/dist/components/Select/SimpleSelect.d.ts.map +1 -0
- package/dist/components/Select/SimpleSelect.js +24 -0
- package/dist/components/Select/SimpleSelect.js.map +1 -0
- package/dist/components/Select/index.d.ts +4 -0
- package/dist/components/Select/index.d.ts.map +1 -0
- package/dist/components/Select/index.js +7 -0
- package/dist/components/Select/index.js.map +1 -0
- package/dist/components/Select/types.d.ts +118 -0
- package/dist/components/Select/types.d.ts.map +1 -0
- package/dist/components/Select/types.js +2 -0
- package/dist/components/Select/types.js.map +1 -0
- package/dist/components/SelectBox.d.ts +65 -0
- package/dist/components/SelectBox.d.ts.map +1 -0
- package/dist/components/SelectBox.js +26 -0
- package/dist/components/SelectBox.js.map +1 -0
- package/dist/components/Skeleton.d.ts +30 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +5 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Slider.d.ts +32 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Slider.js +19 -0
- package/dist/components/Slider.js.map +1 -0
- package/dist/components/SmartTable.d.ts +87 -0
- package/dist/components/SmartTable.d.ts.map +1 -0
- package/dist/components/SmartTable.js +16 -0
- package/dist/components/SmartTable.js.map +1 -0
- package/dist/components/Stepper.d.ts +52 -0
- package/dist/components/Stepper.d.ts.map +1 -0
- package/dist/components/Stepper.js +53 -0
- package/dist/components/Stepper.js.map +1 -0
- package/dist/components/Switch.d.ts +10 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +7 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/Table.d.ts +106 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Table.js +86 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs/TabController.d.ts +11 -0
- package/dist/components/Tabs/TabController.d.ts.map +1 -0
- package/dist/components/Tabs/TabController.js +39 -0
- package/dist/components/Tabs/TabController.js.map +1 -0
- package/dist/components/Tabs/index.d.ts +5 -0
- package/dist/components/Tabs/index.d.ts.map +1 -0
- package/dist/components/Tabs/index.js +37 -0
- package/dist/components/Tabs/index.js.map +1 -0
- package/dist/components/Tabs/types.d.ts +46 -0
- package/dist/components/Tabs/types.d.ts.map +1 -0
- package/dist/components/Tabs/types.js +2 -0
- package/dist/components/Tabs/types.js.map +1 -0
- package/dist/components/Tabs/utils.d.ts +3 -0
- package/dist/components/Tabs/utils.d.ts.map +1 -0
- package/dist/components/Tabs/utils.js +5 -0
- package/dist/components/Tabs/utils.js.map +1 -0
- package/dist/components/Text.d.ts +27 -0
- package/dist/components/Text.d.ts.map +1 -0
- package/dist/components/Text.js +45 -0
- package/dist/components/Text.js.map +1 -0
- package/dist/components/Textarea.d.ts +8 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +4 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/Tooltip.d.ts +25 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +18 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/layout.d.ts +46 -0
- package/dist/components/layout.d.ts.map +1 -0
- package/dist/components/layout.js +18 -0
- package/dist/components/layout.js.map +1 -0
- package/dist/context/CitricContext.d.ts +3 -0
- package/dist/context/CitricContext.d.ts.map +1 -0
- package/dist/context/CitricContext.js +3 -0
- package/dist/context/CitricContext.js.map +1 -0
- package/dist/context/CitricProvider.d.ts +9 -0
- package/dist/context/CitricProvider.d.ts.map +1 -0
- package/dist/context/CitricProvider.js +8 -0
- package/dist/context/CitricProvider.js.map +1 -0
- package/dist/context/hooks.d.ts +2 -0
- package/dist/context/hooks.d.ts.map +1 -0
- package/dist/context/hooks.js +6 -0
- package/dist/context/hooks.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/overlay.d.ts +83 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +199 -0
- package/dist/overlay.js.map +1 -0
- package/dist/theme.css +419 -0
- package/dist/types.d.ts +175 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/ValueController.d.ts +10 -0
- package/dist/utils/ValueController.d.ts.map +1 -0
- package/dist/utils/ValueController.js +32 -0
- package/dist/utils/ValueController.js.map +1 -0
- package/dist/utils/acessibility.d.ts +52 -0
- package/dist/utils/acessibility.d.ts.map +1 -0
- package/dist/utils/acessibility.js +80 -0
- package/dist/utils/acessibility.js.map +1 -0
- package/dist/utils/css.d.ts +12 -0
- package/dist/utils/css.d.ts.map +1 -0
- package/dist/utils/css.js +72 -0
- package/dist/utils/css.js.map +1 -0
- package/dist/utils/options.d.ts +3 -0
- package/dist/utils/options.d.ts.map +1 -0
- package/dist/utils/options.js +7 -0
- package/dist/utils/options.js.map +1 -0
- package/package.json +51 -0
- package/scripts/build-css.ts +49 -0
- package/src/components/Accordion.tsx +74 -0
- package/src/components/Alert.tsx +16 -0
- package/src/components/AsyncContent.tsx +54 -0
- package/src/components/Avatar.tsx +34 -0
- package/src/components/AvatarGroup.tsx +40 -0
- package/src/components/Badge.tsx +28 -0
- package/src/components/Blockquote.tsx +9 -0
- package/src/components/Breadcrumb.tsx +24 -0
- package/src/components/Button.tsx +88 -0
- package/src/components/Card.tsx +32 -0
- package/src/components/Checkbox.tsx +36 -0
- package/src/components/CheckboxGroup.tsx +93 -0
- package/src/components/Circle.tsx +26 -0
- package/src/components/CitricComponent.ts +34 -0
- package/src/components/Divider.tsx +22 -0
- package/src/components/ErrorBoundary.tsx +62 -0
- package/src/components/ErrorMessage.tsx +11 -0
- package/src/components/FallbackBoundary.tsx +29 -0
- package/src/components/Favorite.tsx +37 -0
- package/src/components/FieldGroup.tsx +22 -0
- package/src/components/Form.tsx +17 -0
- package/src/components/FormGroup.tsx +45 -0
- package/src/components/IconBox.tsx +78 -0
- package/src/components/Input.tsx +32 -0
- package/src/components/Link.tsx +40 -0
- package/src/components/LoadingPanel.tsx +8 -0
- package/src/components/MenuOverlay/Menu.tsx +157 -0
- package/src/components/MenuOverlay/context.ts +20 -0
- package/src/components/MenuOverlay/index.tsx +35 -0
- package/src/components/MenuOverlay/keyboard.ts +60 -0
- package/src/components/MenuOverlay/types.ts +178 -0
- package/src/components/Overlay/context.ts +10 -0
- package/src/components/Overlay/index.tsx +137 -0
- package/src/components/Overlay/types.ts +71 -0
- package/src/components/Pagination.tsx +90 -0
- package/src/components/ProgressBar.tsx +25 -0
- package/src/components/ProgressCircular.tsx +29 -0
- package/src/components/RadioGroup.tsx +87 -0
- package/src/components/Rating.tsx +25 -0
- package/src/components/Select/RichSelect.tsx +214 -0
- package/src/components/Select/SimpleSelect.tsx +66 -0
- package/src/components/Select/index.tsx +8 -0
- package/src/components/Select/types.ts +121 -0
- package/src/components/SelectBox.tsx +134 -0
- package/src/components/Skeleton.tsx +41 -0
- package/src/components/Slider.tsx +77 -0
- package/src/components/SmartTable.tsx +148 -0
- package/src/components/Stepper.tsx +142 -0
- package/src/components/Switch.tsx +29 -0
- package/src/components/Table.tsx +219 -0
- package/src/components/Tabs/TabController.ts +40 -0
- package/src/components/Tabs/index.tsx +64 -0
- package/src/components/Tabs/types.ts +48 -0
- package/src/components/Tabs/utils.ts +6 -0
- package/src/components/Text.ts +75 -0
- package/src/components/Textarea.tsx +12 -0
- package/src/components/Tooltip.tsx +53 -0
- package/src/components/layout.tsx +53 -0
- package/src/context/CitricContext.tsx +4 -0
- package/src/context/CitricProvider.tsx +14 -0
- package/src/context/hooks.ts +6 -0
- package/src/index.ts +47 -0
- package/src/overlay.ts +276 -0
- package/src/types.ts +226 -0
- package/src/utils/ValueController.ts +28 -0
- package/src/utils/acessibility.ts +92 -0
- package/src/utils/css.ts +106 -0
- package/src/utils/options.ts +7 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type TagPriority = 'a' | 'button' | 'input' | 'textarea' | 'select' | 'other';
|
|
2
|
+
export type TagPriorityElement = TagPriority | TagPriority[];
|
|
3
|
+
interface FocusOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Instead of focusing the first element overall, focus the first according to this list of priorities.
|
|
6
|
+
*
|
|
7
|
+
* 'other' means elements that are normally not focusable, but have positive tabIndex values.
|
|
8
|
+
*/
|
|
9
|
+
priority?: TagPriorityElement[];
|
|
10
|
+
/**
|
|
11
|
+
* Ignores any element that matches this query selector.
|
|
12
|
+
*/
|
|
13
|
+
ignore?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Focus the first focusable child of the element provided. If the element has no focusable child, nothing happens.
|
|
17
|
+
*
|
|
18
|
+
* A priority list can be passed in the second parameter, as an option. If it's provided, it will focus the first element according to the
|
|
19
|
+
* list.
|
|
20
|
+
*
|
|
21
|
+
* An ignore query selector can also be passed in the options parameter. If the first focusable element matches the query selector, the
|
|
22
|
+
* next element is focused instead.
|
|
23
|
+
*
|
|
24
|
+
* Elements with `auto-focus={false}` will be ignored.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* Suppose the children of element are: h1, button, p, input, select.
|
|
28
|
+
* 1. We don't pass a priority list. The focused element will be the button.
|
|
29
|
+
* 2. Our priority list is ['button']. The focused element will be the button.
|
|
30
|
+
* 3. Our priority list is ['input', 'button']. The focused element will be the input.
|
|
31
|
+
* 4. Our priority list is ['select', 'input']. The focused element will be the select.
|
|
32
|
+
* 5. Our priority list is [['select', 'input'], 'button']. The focused element will be the input.
|
|
33
|
+
*
|
|
34
|
+
* @param element the element to search a child to focus.
|
|
35
|
+
* @param options optional.
|
|
36
|
+
*/
|
|
37
|
+
export declare function focusFirstChild(element: HTMLElement | Document | null | undefined, { priority, ignore }?: FocusOptions): void;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if an element can receive focus.
|
|
40
|
+
*
|
|
41
|
+
* Elements can receive focus only if:
|
|
42
|
+
* - they exist;
|
|
43
|
+
* - they're visible;
|
|
44
|
+
* - they're not disabled;
|
|
45
|
+
* - they are a focusable tag name or have a positive tab index;
|
|
46
|
+
* - they don't have a negative tab index.
|
|
47
|
+
* @param element the element to check.
|
|
48
|
+
* @returns true if the element is focusable, false otherwise.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isFocusable(element?: Element | null): boolean;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=acessibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acessibility.d.ts","sourceRoot":"","sources":["../../src/utils/acessibility.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;AACpF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,WAAW,EAAE,CAAA;AAE5D,UAAU,YAAY;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,EAAE,QAAa,EAAE,MAAM,EAAE,GAAE,YAAiB,QAkB/H;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,WAYnD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const selectors = {
|
|
2
|
+
a: 'a[href]:not(:disabled)',
|
|
3
|
+
button: 'button:not(:disabled)',
|
|
4
|
+
input: 'input:not(:disabled):not([type="hidden"])',
|
|
5
|
+
select: 'textarea:not(:disabled)',
|
|
6
|
+
textarea: 'select:not(:disabled)',
|
|
7
|
+
other: '[tabindex]:not([tabindex="-1"])',
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Focus the first focusable child of the element provided. If the element has no focusable child, nothing happens.
|
|
11
|
+
*
|
|
12
|
+
* A priority list can be passed in the second parameter, as an option. If it's provided, it will focus the first element according to the
|
|
13
|
+
* list.
|
|
14
|
+
*
|
|
15
|
+
* An ignore query selector can also be passed in the options parameter. If the first focusable element matches the query selector, the
|
|
16
|
+
* next element is focused instead.
|
|
17
|
+
*
|
|
18
|
+
* Elements with `auto-focus={false}` will be ignored.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* Suppose the children of element are: h1, button, p, input, select.
|
|
22
|
+
* 1. We don't pass a priority list. The focused element will be the button.
|
|
23
|
+
* 2. Our priority list is ['button']. The focused element will be the button.
|
|
24
|
+
* 3. Our priority list is ['input', 'button']. The focused element will be the input.
|
|
25
|
+
* 4. Our priority list is ['select', 'input']. The focused element will be the select.
|
|
26
|
+
* 5. Our priority list is [['select', 'input'], 'button']. The focused element will be the input.
|
|
27
|
+
*
|
|
28
|
+
* @param element the element to search a child to focus.
|
|
29
|
+
* @param options optional.
|
|
30
|
+
*/
|
|
31
|
+
export function focusFirstChild(element, { priority = [], ignore } = {}) {
|
|
32
|
+
const allFocusableTags = ['a', 'button', 'input', 'other', 'select', 'textarea'];
|
|
33
|
+
const focusableList = [
|
|
34
|
+
element?.querySelectorAll(allFocusableTags.map(t => selectors[t]).join(', ')),
|
|
35
|
+
];
|
|
36
|
+
for (const p of priority) {
|
|
37
|
+
const tags = Array.isArray(p) ? p : [p];
|
|
38
|
+
const querySelectors = tags.map(t => selectors[t]);
|
|
39
|
+
focusableList.unshift(element?.querySelectorAll(querySelectors.join(', ')));
|
|
40
|
+
}
|
|
41
|
+
for (const focusable of focusableList ?? []) {
|
|
42
|
+
for (const f of focusable ?? []) {
|
|
43
|
+
if (f.getAttribute('auto-focus') !== 'false' && (!ignore || !f.matches(ignore))) {
|
|
44
|
+
const styles = window.getComputedStyle(f);
|
|
45
|
+
if (styles.display != 'none' && styles.visibility != 'hidden')
|
|
46
|
+
return f.focus();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Checks if an element can receive focus.
|
|
53
|
+
*
|
|
54
|
+
* Elements can receive focus only if:
|
|
55
|
+
* - they exist;
|
|
56
|
+
* - they're visible;
|
|
57
|
+
* - they're not disabled;
|
|
58
|
+
* - they are a focusable tag name or have a positive tab index;
|
|
59
|
+
* - they don't have a negative tab index.
|
|
60
|
+
* @param element the element to check.
|
|
61
|
+
* @returns true if the element is focusable, false otherwise.
|
|
62
|
+
*/
|
|
63
|
+
export function isFocusable(element) {
|
|
64
|
+
if (!element)
|
|
65
|
+
return false;
|
|
66
|
+
// is disabled: return false
|
|
67
|
+
if (element.ariaDisabled || element.getAttribute('disabled') !== null)
|
|
68
|
+
return false;
|
|
69
|
+
// is invisible: return false
|
|
70
|
+
if (!element.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true }))
|
|
71
|
+
return false;
|
|
72
|
+
// has tab index: return false if negative, true otherwise
|
|
73
|
+
const tabIndexStr = element.getAttribute('tabindex');
|
|
74
|
+
const tabIndex = tabIndexStr ? parseInt(tabIndexStr) : undefined;
|
|
75
|
+
if (tabIndex !== undefined)
|
|
76
|
+
return tabIndex >= 0;
|
|
77
|
+
// check the tag name
|
|
78
|
+
return ['a', 'button', 'input', 'iframe', 'select', 'textarea'].includes(element.tagName.toLowerCase() ?? '');
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=acessibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acessibility.js","sourceRoot":"","sources":["../../src/utils/acessibility.ts"],"names":[],"mappings":"AAgBA,MAAM,SAAS,GAAgC;IAC7C,CAAC,EAAE,wBAAwB;IAC3B,MAAM,EAAE,uBAAuB;IAC/B,KAAK,EAAE,2CAA2C;IAClD,MAAM,EAAE,yBAAyB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,KAAK,EAAE,iCAAiC;CACzC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAAC,OAAkD,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,MAAM,KAAmB,EAAE;IAC9H,MAAM,gBAAgB,GAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC/F,MAAM,aAAa,GAA4C;QAC7D,OAAO,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC9E,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACvC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;QAClD,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7E,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,aAAa,IAAI,EAAE,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,SAAS,IAAI,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAChF,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;gBACzC,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,IAAI,MAAM,CAAC,UAAU,IAAI,QAAQ;oBAAE,OAAO,CAAC,CAAC,KAAK,EAAE,CAAA;YACjF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,OAAwB;IAClD,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IAC1B,4BAA4B;IAC5B,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IACnF,6BAA6B;IAC7B,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IAC5F,0DAA0D;IAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,IAAI,CAAC,CAAA;IAChD,qBAAqB;IACrB,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAC/G,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ColorKey } from '@stack-spot/portal-theme';
|
|
2
|
+
import { TextAppearance, WithStyleShortcuts } from '../types.js';
|
|
3
|
+
export declare function colorNameToColorVariable(name: ColorKey): string;
|
|
4
|
+
export declare function applyColor(style: React.CSSProperties | undefined, color: ColorKey | undefined): import("react").CSSProperties | undefined;
|
|
5
|
+
export declare function textAppearanceToClass(appearance: TextAppearance): string;
|
|
6
|
+
export declare function applyTextAppearance(className: string | undefined, appearance: TextAppearance | undefined): string;
|
|
7
|
+
export declare function applyCSSVariable(style: React.CSSProperties | undefined, name: string, value: any): import("react").CSSProperties | undefined;
|
|
8
|
+
export declare function applyStyles({ bg, fg, border, radius, justifyContent, alignItems, flex, gap, m, mt, mb, ml, mr, p, pt, pb, pl, pr, w, h, style, ...props }: WithStyleShortcuts & Record<string, any>): {
|
|
9
|
+
style: Partial<import("react").CSSProperties>;
|
|
10
|
+
};
|
|
11
|
+
export declare function styleObjectToCssString(styleObject?: React.CSSProperties): string;
|
|
12
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/utils/css.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,0BAA0B,CAAA;AAGvE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAE7D,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAE/D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,SAAS,6CAE7F;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CAExE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,cAAc,GAAG,SAAS,UAExG;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,6CAGhG;AAQD,wBAAgB,WAAW,CACzB,EACE,EAAE,EACF,EAAE,EACF,MAAM,EACN,MAAM,EACN,cAAc,EACd,UAAU,EACV,IAAI,EACJ,GAAG,EACH,CAAC,EACD,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,CAAC,EACD,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,CAAC,EACD,CAAC,EACD,KAAK,EACL,GAAG,KAAK,EACT,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;EA8B5C;AAGD,wBAAgB,sBAAsB,CAAC,WAAW,GAAE,KAAK,CAAC,aAAkB,UAgB3E"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { listToClass, theme } from '@stack-spot/portal-theme';
|
|
2
|
+
import { isNil, omitBy } from 'lodash';
|
|
3
|
+
export function colorNameToColorVariable(name) {
|
|
4
|
+
return `var(--${name.replaceAll('.', '-')})`;
|
|
5
|
+
}
|
|
6
|
+
export function applyColor(style, color) {
|
|
7
|
+
return color ? { ...style, color: colorNameToColorVariable(color) } : style;
|
|
8
|
+
}
|
|
9
|
+
export function textAppearanceToClass(appearance) {
|
|
10
|
+
return `text-${appearance}`;
|
|
11
|
+
}
|
|
12
|
+
export function applyTextAppearance(className, appearance) {
|
|
13
|
+
return listToClass([className, appearance ? textAppearanceToClass(appearance) : undefined]);
|
|
14
|
+
}
|
|
15
|
+
export function applyCSSVariable(style, name, value) {
|
|
16
|
+
if (isNil(value))
|
|
17
|
+
return style;
|
|
18
|
+
return { ...style, [`--${name}`]: `${value}` };
|
|
19
|
+
}
|
|
20
|
+
function spacingToStyle(spacing) {
|
|
21
|
+
if (typeof spacing === 'string')
|
|
22
|
+
return spacing;
|
|
23
|
+
if (typeof spacing === 'number')
|
|
24
|
+
return theme.spacing[spacing];
|
|
25
|
+
return spacing?.map(s => theme.spacing[s]).join(' ');
|
|
26
|
+
}
|
|
27
|
+
export function applyStyles({ bg, fg, border, radius, justifyContent, alignItems, flex, gap, m, mt, mb, ml, mr, p, pt, pb, pl, pr, w, h, style, ...props }) {
|
|
28
|
+
const [bgColor, bgLevel] = bg?.split('.') ?? [];
|
|
29
|
+
const [fgColor, fgLevel] = fg?.split('.') ?? [];
|
|
30
|
+
const [borderColor, borderLevel] = border?.split('.') ?? [];
|
|
31
|
+
const borderColorVar = theme.color[borderColor]?.[borderLevel];
|
|
32
|
+
const newStyle = {
|
|
33
|
+
backgroundColor: theme.color[bgColor]?.[bgLevel],
|
|
34
|
+
color: theme.color[fgColor]?.[fgLevel],
|
|
35
|
+
border: borderColorVar ? `1px solid ${borderColorVar}` : undefined,
|
|
36
|
+
borderRadius: radius ? theme.radius[radius] : undefined,
|
|
37
|
+
justifyContent,
|
|
38
|
+
alignItems,
|
|
39
|
+
flex,
|
|
40
|
+
gap,
|
|
41
|
+
margin: spacingToStyle(m),
|
|
42
|
+
marginTop: spacingToStyle(mt),
|
|
43
|
+
marginBottom: spacingToStyle(mb),
|
|
44
|
+
marginLeft: spacingToStyle(ml),
|
|
45
|
+
marginRight: spacingToStyle(mr),
|
|
46
|
+
padding: spacingToStyle(p),
|
|
47
|
+
paddingTop: spacingToStyle(pt),
|
|
48
|
+
paddingBottom: spacingToStyle(pb),
|
|
49
|
+
paddingLeft: spacingToStyle(pl),
|
|
50
|
+
paddingRight: spacingToStyle(pr),
|
|
51
|
+
width: w,
|
|
52
|
+
height: h,
|
|
53
|
+
...style,
|
|
54
|
+
};
|
|
55
|
+
return { style: omitBy(newStyle, v => v === undefined), ...props };
|
|
56
|
+
}
|
|
57
|
+
// AI generated
|
|
58
|
+
export function styleObjectToCssString(styleObject = {}) {
|
|
59
|
+
return Object.entries(styleObject)
|
|
60
|
+
.map(([property, value]) => {
|
|
61
|
+
// Convert camelCase to kebab-case
|
|
62
|
+
const cssProperty = property.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
63
|
+
// Append 'px' to numeric values for common dimension properties
|
|
64
|
+
const cssValue = typeof value === "number" &&
|
|
65
|
+
!['zIndex', 'opacity', 'fontWeight'].includes(property)
|
|
66
|
+
? `${value}px`
|
|
67
|
+
: value;
|
|
68
|
+
return `${cssProperty}: ${cssValue}`;
|
|
69
|
+
})
|
|
70
|
+
.join("; ");
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/utils/css.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/utils/options.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,GAAG,UAE7C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,sBAE3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/utils/options.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,MAAW;IAC5C,OAAO,GAAG,MAAM,EAAE,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAW;IAC1C,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AAC/E,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stack-spot/citric-react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "StackSpot",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"typings": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./theme.css": "./dist/theme.css",
|
|
10
|
+
"./citric.css": "./dist/citric.css"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/stack-spot/citric"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@stack-spot/citric-icons": ">=0.1.0",
|
|
19
|
+
"@stack-spot/portal-theme": ">=1.2.0",
|
|
20
|
+
"@stack-spot/portal-translate": ">=1.2.2",
|
|
21
|
+
"lodash": ">=4.17.21",
|
|
22
|
+
"react": ">=18",
|
|
23
|
+
"react-dom": ">=18"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/lodash": "^4.14.177",
|
|
27
|
+
"@types/react": "^18.2.6",
|
|
28
|
+
"@types/react-dom": "18.2.3",
|
|
29
|
+
"@types/yargs": "^17.0.33",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
|
31
|
+
"@typescript-eslint/parser": "^7.12.0",
|
|
32
|
+
"eslint": "^8.53.0",
|
|
33
|
+
"eslint-plugin-filenames": "^1.3.2",
|
|
34
|
+
"eslint-plugin-import": "^2.29.0",
|
|
35
|
+
"eslint-plugin-lodash": "^7.4.0",
|
|
36
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
37
|
+
"eslint-plugin-react": "^7.33.2",
|
|
38
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
39
|
+
"eslint-plugin-react-refresh": "^0.4.4",
|
|
40
|
+
"glob": "^11.0.3",
|
|
41
|
+
"rimraf": "^5.0.7",
|
|
42
|
+
"tsc-esm-fix": "^2.20.26",
|
|
43
|
+
"tsx": "^4.19.4",
|
|
44
|
+
"typescript": "^5.3.3",
|
|
45
|
+
"yargs": "^18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "rimraf dist && tsc && tsc-esm-fix --target='dist' && pnpm tsx scripts/build-css.ts",
|
|
49
|
+
"lint": "eslint ./src/**/*.{ts,tsx}"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'fs/promises'
|
|
2
|
+
import { glob } from 'glob'
|
|
3
|
+
import yargs from 'yargs'
|
|
4
|
+
import { hideBin } from 'yargs/helpers'
|
|
5
|
+
|
|
6
|
+
interface Argv {
|
|
7
|
+
o?: string,
|
|
8
|
+
output?: string,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getArguments() {
|
|
12
|
+
const argv = yargs(hideBin(process.argv)).parse() as Argv
|
|
13
|
+
const output = argv.o || argv.output || './dist'
|
|
14
|
+
return { output }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function readInput() {
|
|
18
|
+
const themeFiles = await glob('../css/theme/**.css')
|
|
19
|
+
const otherFiles = await glob('../css/**/**.css', { ignore: '../css/theme/**' })
|
|
20
|
+
const themeCss: string[] = []
|
|
21
|
+
const otherCss: string[] = []
|
|
22
|
+
for (const f of themeFiles) {
|
|
23
|
+
themeCss.push(await readFile(f, { encoding: 'utf8' }))
|
|
24
|
+
}
|
|
25
|
+
for (const f of otherFiles) {
|
|
26
|
+
otherCss.push(await readFile(f, { encoding: 'utf8' }))
|
|
27
|
+
}
|
|
28
|
+
return { theme: themeCss.join('\n\n'), citric: otherCss.join('\n\n') }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function start() {
|
|
32
|
+
try {
|
|
33
|
+
const { output } = getArguments()
|
|
34
|
+
const { theme, citric } = await readInput()
|
|
35
|
+
await Promise.all([
|
|
36
|
+
writeFile(`${output}/theme.css`, theme, { encoding: 'utf8' }),
|
|
37
|
+
writeFile(`${output}/citric.css`, citric, { encoding: 'utf8' }),
|
|
38
|
+
])
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.log(`CSS built at ${output}`)
|
|
41
|
+
process.exit(0)
|
|
42
|
+
} catch (error) {
|
|
43
|
+
// eslint-disable-next-line no-console
|
|
44
|
+
console.error(error)
|
|
45
|
+
process.exit(1)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
start()
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react'
|
|
3
|
+
import { HTMLExtension } from '../types'
|
|
4
|
+
import { applyCSSVariable } from '../utils/css'
|
|
5
|
+
import { CitricComponent } from './CitricComponent'
|
|
6
|
+
|
|
7
|
+
export interface BaseAccordionProps {
|
|
8
|
+
/**
|
|
9
|
+
* A unique id for this accordion.
|
|
10
|
+
*/
|
|
11
|
+
id?: string,
|
|
12
|
+
/**
|
|
13
|
+
* The Accordion's appearance. If unset, the appearance is customizable.
|
|
14
|
+
*/
|
|
15
|
+
appearance?: 'card',
|
|
16
|
+
/**
|
|
17
|
+
* Controls the expansion state of the accordion.
|
|
18
|
+
*/
|
|
19
|
+
expanded?: boolean,
|
|
20
|
+
/**
|
|
21
|
+
* Controls the expansion state of the accordion. Called when the accordion is expanded or collapsed.
|
|
22
|
+
*/
|
|
23
|
+
onChange?: (expanded: boolean) => void,
|
|
24
|
+
/**
|
|
25
|
+
* The header for the accordion, i.e. the part that is always rendered. You can use either a simple title or a custom set of components,
|
|
26
|
+
* in the second case, you may pass a function that receives the "expand/collapse" button as parameter.
|
|
27
|
+
*/
|
|
28
|
+
header: React.ReactNode | ((expandButton: React.ReactElement) => React.ReactNode),
|
|
29
|
+
/**
|
|
30
|
+
* The maximum height for the accordion.
|
|
31
|
+
*
|
|
32
|
+
* @default 300
|
|
33
|
+
*/
|
|
34
|
+
maxHeight?: number,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type AccordionProps = HTMLExtension<'div', BaseAccordionProps, 'onChange'>
|
|
38
|
+
|
|
39
|
+
export const Accordion = (
|
|
40
|
+
{ id, appearance, expanded, onChange, header, maxHeight = 300, className, style, children, ...props }: AccordionProps,
|
|
41
|
+
) => {
|
|
42
|
+
const [ariaHidden, setAriaHidden] = useState(!expanded)
|
|
43
|
+
const accordionId = useMemo(() => id || `${Math.random()}`, [id])
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
setAriaHidden(!expanded)
|
|
47
|
+
}, [expanded])
|
|
48
|
+
|
|
49
|
+
const expandBtn = <input
|
|
50
|
+
type="checkbox"
|
|
51
|
+
checked={expanded}
|
|
52
|
+
onChange={() => {
|
|
53
|
+
setAriaHidden(!ariaHidden)
|
|
54
|
+
onChange?.(!expanded)
|
|
55
|
+
}}
|
|
56
|
+
onKeyDown={e => e.key === 'Enter' && (e.target as HTMLElement).click?.()}
|
|
57
|
+
aria-controls={accordionId}
|
|
58
|
+
/>
|
|
59
|
+
const headerContent = typeof header === 'function' ? header(expandBtn) : <label>{header}{expandBtn}</label>
|
|
60
|
+
return (
|
|
61
|
+
<CitricComponent
|
|
62
|
+
tag="div"
|
|
63
|
+
component="accordion"
|
|
64
|
+
className={listToClass([appearance, className])}
|
|
65
|
+
style={applyCSSVariable(style, 'max-height', `${maxHeight}px`)}
|
|
66
|
+
{...props}
|
|
67
|
+
>
|
|
68
|
+
<header>{headerContent}</header>
|
|
69
|
+
<section id={accordionId} aria-hidden={ariaHidden} {...(ariaHidden ? { inert: 'true' } : {})}>
|
|
70
|
+
{appearance === 'card' ? <div className="content">{children}</div> : children}
|
|
71
|
+
</section>
|
|
72
|
+
</CitricComponent>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { HTMLExtension } from '../types'
|
|
3
|
+
import { CitricComponent } from './CitricComponent'
|
|
4
|
+
|
|
5
|
+
export interface BaseAlertProps {
|
|
6
|
+
/**
|
|
7
|
+
* Type of the message.
|
|
8
|
+
* @default 'warning'
|
|
9
|
+
*/
|
|
10
|
+
type?: 'error' | 'info' | 'warning',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type AlertProps = HTMLExtension<'div', BaseAlertProps>
|
|
14
|
+
|
|
15
|
+
export const Alert = ({ type, className, children, ...props }: AlertProps) =>
|
|
16
|
+
<CitricComponent tag="div" component="alert" className={listToClass([type, className])} {...props}>{children}</CitricComponent>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { MutableRefObject, useEffect, useLayoutEffect } from 'react'
|
|
2
|
+
import { useCitricController } from '../context/hooks'
|
|
3
|
+
import { ErrorMessage } from './ErrorMessage'
|
|
4
|
+
import { LoadingPanel } from './LoadingPanel'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
/**
|
|
8
|
+
* Whether or not to show the loading feedback.
|
|
9
|
+
*/
|
|
10
|
+
loading: boolean,
|
|
11
|
+
/**
|
|
12
|
+
* A javascript error. Used to show error feedbacks.
|
|
13
|
+
*/
|
|
14
|
+
error?: any,
|
|
15
|
+
/**
|
|
16
|
+
* If provided, this element will receive focus as soon as the content is loaded and has no errors.
|
|
17
|
+
* Can be either a React Ref Object or a query selector.
|
|
18
|
+
*/
|
|
19
|
+
autofocus?: string | MutableRefObject<HTMLElement>,
|
|
20
|
+
/**
|
|
21
|
+
* The content to show if it's not loading or has errors.
|
|
22
|
+
*/
|
|
23
|
+
children: React.ReactNode,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Renders a component that provides user feedback on async requests.
|
|
28
|
+
* It renders either a loading component, an error component (which is received as prop)
|
|
29
|
+
* or the received children props.
|
|
30
|
+
*
|
|
31
|
+
* @param options the props for rendering the component: {@link Props}.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
export const AsyncContent = ({ loading, error, autofocus, children }: Props) => {
|
|
35
|
+
const citric = useCitricController()
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (error) {
|
|
39
|
+
citric?.onError?.(error)
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.error(error)
|
|
42
|
+
}
|
|
43
|
+
}, [error])
|
|
44
|
+
|
|
45
|
+
useLayoutEffect(() => {
|
|
46
|
+
if (!loading && !error) {
|
|
47
|
+
typeof autofocus === 'string' ? (document.querySelector(autofocus) as HTMLElement)?.focus?.() : autofocus?.current?.focus()
|
|
48
|
+
}
|
|
49
|
+
}, [loading, error])
|
|
50
|
+
|
|
51
|
+
if (loading) return <LoadingPanel />
|
|
52
|
+
if (error) return citric?.renderError ? citric.renderError(error) : <ErrorMessage error={error} />
|
|
53
|
+
return children
|
|
54
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { HTMLExtension, WithColorPalette } from '../types'
|
|
3
|
+
import { CitricComponent } from './CitricComponent'
|
|
4
|
+
|
|
5
|
+
export interface BaseAvatarProps extends WithColorPalette {
|
|
6
|
+
/**
|
|
7
|
+
* @default 'lg'
|
|
8
|
+
*/
|
|
9
|
+
size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
|
|
10
|
+
/**
|
|
11
|
+
* This name will be reduced to a maximum of 2 capital letters (first letter of each word).
|
|
12
|
+
*/
|
|
13
|
+
name?: string,
|
|
14
|
+
/**
|
|
15
|
+
* @default 'circle'
|
|
16
|
+
*/
|
|
17
|
+
appearance?: 'square' | 'circle',
|
|
18
|
+
/**
|
|
19
|
+
* If instead of the name you want to use an image, this should be the image's url.
|
|
20
|
+
*/
|
|
21
|
+
image?: string,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type AvatarProps = HTMLExtension<'div', BaseAvatarProps, 'children'>
|
|
25
|
+
|
|
26
|
+
export const Avatar = ({ size, name, appearance, className, image, ...props }: AvatarProps) => {
|
|
27
|
+
const parts = name?.split(' ') ?? ['']
|
|
28
|
+
const acronym = parts.length >= 2 ? `${parts[0][0]}${parts[1][0]}` : parts[0][0]
|
|
29
|
+
return (
|
|
30
|
+
<CitricComponent tag="div" component="avatar" className={listToClass([size, appearance, className])} {...props}>
|
|
31
|
+
{image ? <img src={image} /> : acronym}
|
|
32
|
+
</CitricComponent>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { HTMLExtension, WithColorPalette } from '../types'
|
|
3
|
+
import { Avatar } from './Avatar'
|
|
4
|
+
import { CitricComponent } from './CitricComponent'
|
|
5
|
+
|
|
6
|
+
export interface BaseAvatarGroupProps extends WithColorPalette {
|
|
7
|
+
/**
|
|
8
|
+
* @default 'lg'
|
|
9
|
+
*/
|
|
10
|
+
size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
|
|
11
|
+
/**
|
|
12
|
+
* @default 'circle'
|
|
13
|
+
*/
|
|
14
|
+
appearance?: 'square' | 'circle',
|
|
15
|
+
/**
|
|
16
|
+
* The avatars in the group. Use "image" for rendering images instead of the avatar.
|
|
17
|
+
*/
|
|
18
|
+
items: { name?: string, image?: string }[],
|
|
19
|
+
/**
|
|
20
|
+
* A maximum number of avatars to show in the group.
|
|
21
|
+
**/
|
|
22
|
+
maxItems?: number,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type AvatarGroupProps = HTMLExtension<'div', BaseAvatarGroupProps, 'children'>
|
|
26
|
+
|
|
27
|
+
export const AvatarGroup = ({ size, items, appearance, maxItems, className, ...props }: AvatarGroupProps) => {
|
|
28
|
+
const avatars = items.map(({ name, image }) => <Avatar key={name} name={name} image={image} />, [items])
|
|
29
|
+
return (
|
|
30
|
+
<CitricComponent
|
|
31
|
+
tag="div"
|
|
32
|
+
component="avatar-group"
|
|
33
|
+
className={listToClass([size, appearance, className])}
|
|
34
|
+
data-max-items={maxItems}
|
|
35
|
+
{...props}
|
|
36
|
+
>
|
|
37
|
+
{avatars}
|
|
38
|
+
</CitricComponent>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { HTMLExtension, WithColorPalette } from '../types'
|
|
3
|
+
import { CitricComponent } from './CitricComponent'
|
|
4
|
+
|
|
5
|
+
type ValidTags = 'a' | 'button' | 'li' | 'div' | 'span'
|
|
6
|
+
|
|
7
|
+
export interface BaseBadgeProps<T extends ValidTags = ValidTags> extends WithColorPalette {
|
|
8
|
+
/**
|
|
9
|
+
* @default 'div'
|
|
10
|
+
*/
|
|
11
|
+
tag?: T,
|
|
12
|
+
/**
|
|
13
|
+
* Determines how round the corners are.
|
|
14
|
+
*
|
|
15
|
+
* @default 'circle'
|
|
16
|
+
*/
|
|
17
|
+
appearance?: 'square' | 'circle',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type BadgeProps<T extends ValidTags> = HTMLExtension<T, BaseBadgeProps<T>>
|
|
21
|
+
|
|
22
|
+
export function Badge<T extends ValidTags>({ tag, appearance, className, children, ...props }: BadgeProps<T>) {
|
|
23
|
+
return (
|
|
24
|
+
<CitricComponent tag={tag || 'div'} component="badge" className={listToClass([appearance, className])} {...props as any}>
|
|
25
|
+
{children}
|
|
26
|
+
</CitricComponent>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HTMLExtension, WithColorPalette, WithColorScheme } from '../types'
|
|
2
|
+
import { CitricComponent } from './CitricComponent'
|
|
3
|
+
|
|
4
|
+
export type BaseBlockquoteProps = WithColorScheme & WithColorPalette
|
|
5
|
+
|
|
6
|
+
export type BlockquoteProps = HTMLExtension<'blockquote', BaseBlockquoteProps>
|
|
7
|
+
|
|
8
|
+
export const Blockquote = ({ children, ...props }: BlockquoteProps) =>
|
|
9
|
+
<CitricComponent tag="blockquote" component="blockquote" {...props}>{children}</CitricComponent>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { HTMLExtension } from '../types'
|
|
3
|
+
import { CitricComponent } from './CitricComponent'
|
|
4
|
+
|
|
5
|
+
interface BreadCrumbItem {
|
|
6
|
+
label: string,
|
|
7
|
+
href?: string,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface BaseBreadcrumbProps {
|
|
11
|
+
items: BreadCrumbItem[],
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type BreadcrumbProps = HTMLExtension<'nav', BaseBreadcrumbProps, 'children'>
|
|
15
|
+
|
|
16
|
+
export const Breadcrumb = ({ items, ...props }: BreadcrumbProps) => {
|
|
17
|
+
const children = useMemo(
|
|
18
|
+
() => items.map(
|
|
19
|
+
(item, index) => item.href ? <li key={index}><a href={item.href}>{item.label}</a></li> : <li key={index}>{item.label}</li>,
|
|
20
|
+
),
|
|
21
|
+
[items],
|
|
22
|
+
)
|
|
23
|
+
return <CitricComponent tag="nav" component="breadcrumb" {...props}><ul>{children}</ul></CitricComponent>
|
|
24
|
+
}
|