@panneau/ui 0.0.0-stage → 5.0.0-alpha.1
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/README.md +74 -2
- package/dist/alert/Alert.css +78 -0
- package/dist/alert/Alert.d.ts +30 -0
- package/dist/alert/Alert.d.ts.map +1 -0
- package/dist/alert/Alert.js +64 -0
- package/dist/alert/Alert.js.map +1 -0
- package/dist/alert/Alert.module.js +30 -0
- package/dist/alert/Alert.module.js.map +1 -0
- package/dist/badge/Badge.css +60 -0
- package/dist/badge/Badge.d.ts +15 -0
- package/dist/badge/Badge.d.ts.map +1 -0
- package/dist/badge/Badge.js +21 -0
- package/dist/badge/Badge.js.map +1 -0
- package/dist/badge/Badge.module.js +22 -0
- package/dist/badge/Badge.module.js.map +1 -0
- package/dist/button/Button.css +112 -0
- package/dist/button/Button.d.ts +26 -0
- package/dist/button/Button.d.ts.map +1 -0
- package/dist/button/Button.js +39 -0
- package/dist/button/Button.js.map +1 -0
- package/dist/button/Button.module.js +28 -0
- package/dist/button/Button.module.js.map +1 -0
- package/dist/card/Card.css +50 -0
- package/dist/card/Card.d.ts +20 -0
- package/dist/card/Card.d.ts.map +1 -0
- package/dist/card/Card.js +38 -0
- package/dist/card/Card.js.map +1 -0
- package/dist/card/Card.module.js +18 -0
- package/dist/card/Card.module.js.map +1 -0
- package/dist/checkbox/Checkbox.css +79 -0
- package/dist/checkbox/Checkbox.d.ts +11 -0
- package/dist/checkbox/Checkbox.d.ts.map +1 -0
- package/dist/checkbox/Checkbox.js +43 -0
- package/dist/checkbox/Checkbox.js.map +1 -0
- package/dist/checkbox/Checkbox.module.js +16 -0
- package/dist/checkbox/Checkbox.module.js.map +1 -0
- package/dist/checkbox/ChoiceChrome.d.ts +15 -0
- package/dist/checkbox/ChoiceChrome.d.ts.map +1 -0
- package/dist/checkbox/ChoiceChrome.js +36 -0
- package/dist/checkbox/ChoiceChrome.js.map +1 -0
- package/dist/combo-box/ComboBox.css +26 -0
- package/dist/combo-box/ComboBox.d.ts +30 -0
- package/dist/combo-box/ComboBox.d.ts.map +1 -0
- package/dist/combo-box/ComboBox.js +106 -0
- package/dist/combo-box/ComboBox.js.map +1 -0
- package/dist/combo-box/ComboBox.module.js +14 -0
- package/dist/combo-box/ComboBox.module.js.map +1 -0
- package/dist/date-picker/DatePicker.css +135 -0
- package/dist/date-picker/DatePicker.d.ts +12 -0
- package/dist/date-picker/DatePicker.d.ts.map +1 -0
- package/dist/date-picker/DatePicker.js +93 -0
- package/dist/date-picker/DatePicker.js.map +1 -0
- package/dist/date-picker/DatePicker.module.js +30 -0
- package/dist/date-picker/DatePicker.module.js.map +1 -0
- package/dist/dialog/Dialog.css +126 -0
- package/dist/dialog/Dialog.d.ts +31 -0
- package/dist/dialog/Dialog.d.ts.map +1 -0
- package/dist/dialog/Dialog.js +61 -0
- package/dist/dialog/Dialog.js.map +1 -0
- package/dist/dialog/Dialog.module.js +30 -0
- package/dist/dialog/Dialog.module.js.map +1 -0
- package/dist/disclosure/Disclosure.css +54 -0
- package/dist/disclosure/Disclosure.d.ts +20 -0
- package/dist/disclosure/Disclosure.d.ts.map +1 -0
- package/dist/disclosure/Disclosure.js +43 -0
- package/dist/disclosure/Disclosure.js.map +1 -0
- package/dist/disclosure/Disclosure.module.js +22 -0
- package/dist/disclosure/Disclosure.module.js.map +1 -0
- package/dist/field/Field.css +145 -0
- package/dist/field/Field.module.js +30 -0
- package/dist/field/Field.module.js.map +1 -0
- package/dist/field/FieldParts.d.ts +32 -0
- package/dist/field/FieldParts.d.ts.map +1 -0
- package/dist/field/FieldParts.js +56 -0
- package/dist/field/FieldParts.js.map +1 -0
- package/dist/field/Fieldset.d.ts +22 -0
- package/dist/field/Fieldset.d.ts.map +1 -0
- package/dist/field/Fieldset.js +50 -0
- package/dist/field/Fieldset.js.map +1 -0
- package/dist/icon/Icon.css +5 -0
- package/dist/icon/Icon.d.ts +31 -0
- package/dist/icon/Icon.d.ts.map +1 -0
- package/dist/icon/Icon.js +29 -0
- package/dist/icon/Icon.js.map +1 -0
- package/dist/icon/Icon.module.js +8 -0
- package/dist/icon/Icon.module.js.map +1 -0
- package/dist/icon/namedIcons.d.ts +16 -0
- package/dist/icon/namedIcons.d.ts.map +1 -0
- package/dist/icon/namedIcons.js +90 -0
- package/dist/icon/namedIcons.js.map +1 -0
- package/dist/icon-button/IconButton.css +9 -0
- package/dist/icon-button/IconButton.d.ts +15 -0
- package/dist/icon-button/IconButton.d.ts.map +1 -0
- package/dist/icon-button/IconButton.js +26 -0
- package/dist/icon-button/IconButton.js.map +1 -0
- package/dist/icon-button/IconButton.module.js +12 -0
- package/dist/icon-button/IconButton.module.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/intl/messages.d.ts +2 -0
- package/dist/intl/messages.d.ts.map +1 -0
- package/dist/intl/messages.js +1 -0
- package/dist/intl/usePanneauIntl.d.ts +7 -0
- package/dist/intl/usePanneauIntl.d.ts.map +1 -0
- package/dist/intl/usePanneauIntl.js +22 -0
- package/dist/intl/usePanneauIntl.js.map +1 -0
- package/dist/locales/index.d.ts +15 -0
- package/dist/locales/index.d.ts.map +1 -0
- package/dist/locales/index.js +21 -0
- package/dist/locales/index.js.map +1 -0
- package/dist/menu/Menu.d.ts +27 -0
- package/dist/menu/Menu.d.ts.map +1 -0
- package/dist/menu/Menu.js +57 -0
- package/dist/menu/Menu.js.map +1 -0
- package/dist/number-input/NumberInput.css +57 -0
- package/dist/number-input/NumberInput.d.ts +21 -0
- package/dist/number-input/NumberInput.d.ts.map +1 -0
- package/dist/number-input/NumberInput.js +82 -0
- package/dist/number-input/NumberInput.js.map +1 -0
- package/dist/number-input/NumberInput.module.js +16 -0
- package/dist/number-input/NumberInput.module.js.map +1 -0
- package/dist/popover/Popover.css +32 -0
- package/dist/popover/Popover.d.ts +18 -0
- package/dist/popover/Popover.d.ts.map +1 -0
- package/dist/popover/Popover.js +41 -0
- package/dist/popover/Popover.js.map +1 -0
- package/dist/popover/Popover.module.js +14 -0
- package/dist/popover/Popover.module.js.map +1 -0
- package/dist/radio-group/RadioGroup.css +83 -0
- package/dist/radio-group/RadioGroup.d.ts +12 -0
- package/dist/radio-group/RadioGroup.d.ts.map +1 -0
- package/dist/radio-group/RadioGroup.js +61 -0
- package/dist/radio-group/RadioGroup.js.map +1 -0
- package/dist/radio-group/RadioGroup.module.js +20 -0
- package/dist/radio-group/RadioGroup.module.js.map +1 -0
- package/dist/root/PanneauRoot.css +251 -0
- package/dist/root/PanneauRoot.d.ts +34 -0
- package/dist/root/PanneauRoot.d.ts.map +1 -0
- package/dist/root/PanneauRoot.js +84 -0
- package/dist/root/PanneauRoot.js.map +1 -0
- package/dist/root/PanneauRoot.module.js +12 -0
- package/dist/root/PanneauRoot.module.js.map +1 -0
- package/dist/select/ListBox.css +104 -0
- package/dist/select/ListBox.module.js +32 -0
- package/dist/select/ListBox.module.js.map +1 -0
- package/dist/select/Select.d.ts +45 -0
- package/dist/select/Select.d.ts.map +1 -0
- package/dist/select/Select.js +136 -0
- package/dist/select/Select.js.map +1 -0
- package/dist/spinner/Spinner.css +40 -0
- package/dist/spinner/Spinner.d.ts +11 -0
- package/dist/spinner/Spinner.d.ts.map +1 -0
- package/dist/spinner/Spinner.js +25 -0
- package/dist/spinner/Spinner.js.map +1 -0
- package/dist/spinner/Spinner.module.js +18 -0
- package/dist/spinner/Spinner.module.js.map +1 -0
- package/dist/switch/Switch.css +69 -0
- package/dist/switch/Switch.d.ts +11 -0
- package/dist/switch/Switch.d.ts.map +1 -0
- package/dist/switch/Switch.js +33 -0
- package/dist/switch/Switch.js.map +1 -0
- package/dist/switch/Switch.module.js +15 -0
- package/dist/switch/Switch.module.js.map +1 -0
- package/dist/tabs/Tabs.css +83 -0
- package/dist/tabs/Tabs.d.ts +27 -0
- package/dist/tabs/Tabs.d.ts.map +1 -0
- package/dist/tabs/Tabs.js +141 -0
- package/dist/tabs/Tabs.js.map +1 -0
- package/dist/tabs/Tabs.module.js +16 -0
- package/dist/tabs/Tabs.module.js.map +1 -0
- package/dist/text-area/TextArea.css +8 -0
- package/dist/text-area/TextArea.d.ts +11 -0
- package/dist/text-area/TextArea.d.ts.map +1 -0
- package/dist/text-area/TextArea.js +41 -0
- package/dist/text-area/TextArea.js.map +1 -0
- package/dist/text-area/TextArea.module.js +8 -0
- package/dist/text-area/TextArea.module.js.map +1 -0
- package/dist/text-input/TextInput.d.ts +17 -0
- package/dist/text-input/TextInput.d.ts.map +1 -0
- package/dist/text-input/TextInput.js +61 -0
- package/dist/text-input/TextInput.js.map +1 -0
- package/dist/theme/bootstrap.d.ts +8 -0
- package/dist/theme/bootstrap.d.ts.map +1 -0
- package/dist/theme/bootstrap.js +61 -0
- package/dist/theme/bootstrap.js.map +1 -0
- package/dist/theme/theme.d.ts +23 -0
- package/dist/theme/theme.d.ts.map +1 -0
- package/dist/theme/theme.js +30 -0
- package/dist/theme/theme.js.map +1 -0
- package/dist/time-input/TimeInput.d.ts +8 -0
- package/dist/time-input/TimeInput.d.ts.map +1 -0
- package/dist/time-input/TimeInput.js +45 -0
- package/dist/time-input/TimeInput.js.map +1 -0
- package/dist/toast/Toast.css +109 -0
- package/dist/toast/Toast.d.ts +39 -0
- package/dist/toast/Toast.d.ts.map +1 -0
- package/dist/toast/Toast.js +152 -0
- package/dist/toast/Toast.js.map +1 -0
- package/dist/toast/Toast.module.js +30 -0
- package/dist/toast/Toast.module.js.map +1 -0
- package/dist/tooltip/Tooltip.css +25 -0
- package/dist/tooltip/Tooltip.d.ts +19 -0
- package/dist/tooltip/Tooltip.d.ts.map +1 -0
- package/dist/tooltip/Tooltip.js +29 -0
- package/dist/tooltip/Tooltip.js.map +1 -0
- package/dist/tooltip/Tooltip.module.js +12 -0
- package/dist/tooltip/Tooltip.module.js.map +1 -0
- package/dist/utils/cx.d.ts +3 -0
- package/dist/utils/cx.d.ts.map +1 -0
- package/dist/utils/cx.js +9 -0
- package/dist/utils/cx.js.map +1 -0
- package/package.json +48 -5
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { cx } from "../utils/cx.js";
|
|
2
|
+
import { getThemeCss, hashString } from "../theme/theme.js";
|
|
3
|
+
import { ToastProvider } from "../toast/Toast.js";
|
|
4
|
+
import PanneauRoot_module_default from "./PanneauRoot.module.js";
|
|
5
|
+
import { I18nProvider } from "react-aria-components";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { getPanneauMessages } from "@panneau/intl";
|
|
8
|
+
import { createContext, use, useState } from "react";
|
|
9
|
+
import { IntlContext, IntlProvider } from "react-intl";
|
|
10
|
+
//#region src/root/PanneauRoot.tsx
|
|
11
|
+
/** `undefined` outside of a root, `null` while the root's container isn't mounted yet. */
|
|
12
|
+
var PortalContext = createContext(void 0);
|
|
13
|
+
/**
|
|
14
|
+
* The element overlays render into: the closest `PanneauRoot`'s, or `undefined` for the body
|
|
15
|
+
* without a root. It is `null` during the first render of a root: overlays wait for it, since
|
|
16
|
+
* React Aria hides everything outside of a modal from assistive technologies when it opens.
|
|
17
|
+
*/
|
|
18
|
+
function usePortalContainer() {
|
|
19
|
+
return use(PortalContext);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* An `IntlProvider` with Panneau's messages in a locale, for a root without one above it. A locale
|
|
23
|
+
* Panneau doesn't translate gets English, so that react-intl doesn't report every message as
|
|
24
|
+
* missing.
|
|
25
|
+
*/
|
|
26
|
+
function PanneauIntlProvider({ locale = "en", children }) {
|
|
27
|
+
const messages = getPanneauMessages(locale);
|
|
28
|
+
const translated = Object.keys(messages).length > 0;
|
|
29
|
+
return /* @__PURE__ */ jsx(IntlProvider, {
|
|
30
|
+
locale: translated ? locale : "en",
|
|
31
|
+
defaultLocale: "en",
|
|
32
|
+
messages: translated ? messages : getPanneauMessages("en"),
|
|
33
|
+
children
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The root of every Panneau interface. It scopes the base stylesheet and the design tokens to its
|
|
38
|
+
* element (no global CSS), applies a theme and a color scheme, and hosts overlays and toasts so
|
|
39
|
+
* that they get the tokens too. Panneau components must render inside one. A project can override
|
|
40
|
+
* any token with its own class on the root. Without an `IntlProvider` above it, it provides one
|
|
41
|
+
* with Panneau's messages in its `locale`.
|
|
42
|
+
*/
|
|
43
|
+
function PanneauRoot({ theme = null, colorScheme = "light", locale, className, children, ...props }) {
|
|
44
|
+
const intl = use(IntlContext);
|
|
45
|
+
const [container, setContainer] = useState(null);
|
|
46
|
+
const css = theme !== null ? getThemeCss(theme, "§") : "";
|
|
47
|
+
const scope = css !== "" ? hashString(css) : void 0;
|
|
48
|
+
const root = /* @__PURE__ */ jsxs("div", {
|
|
49
|
+
...props,
|
|
50
|
+
className: cx(PanneauRoot_module_default.root, className),
|
|
51
|
+
"data-color-scheme": colorScheme,
|
|
52
|
+
"data-panneau-theme": scope,
|
|
53
|
+
children: [scope !== void 0 ? /* @__PURE__ */ jsx("style", {
|
|
54
|
+
href: `panneau-theme-${scope}`,
|
|
55
|
+
precedence: "panneau",
|
|
56
|
+
children: css.replaceAll("§", scope)
|
|
57
|
+
}) : null, /* @__PURE__ */ jsxs(I18nProvider, {
|
|
58
|
+
locale: locale ?? intl?.locale,
|
|
59
|
+
children: [/* @__PURE__ */ jsx(PortalContext, {
|
|
60
|
+
value: container,
|
|
61
|
+
children: /* @__PURE__ */ jsx(ToastProvider, {
|
|
62
|
+
regionClassName: PanneauRoot_module_default.root,
|
|
63
|
+
regionProps: {
|
|
64
|
+
"data-color-scheme": colorScheme,
|
|
65
|
+
"data-panneau-theme": scope
|
|
66
|
+
},
|
|
67
|
+
children
|
|
68
|
+
})
|
|
69
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
70
|
+
ref: setContainer,
|
|
71
|
+
className: PanneauRoot_module_default.portal
|
|
72
|
+
})]
|
|
73
|
+
})]
|
|
74
|
+
});
|
|
75
|
+
if (intl === null || intl === void 0) return /* @__PURE__ */ jsx(PanneauIntlProvider, {
|
|
76
|
+
locale,
|
|
77
|
+
children: root
|
|
78
|
+
});
|
|
79
|
+
return root;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { PanneauRoot, usePortalContainer };
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=PanneauRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanneauRoot.js","names":["styles"],"sources":["../../src/root/PanneauRoot.tsx"],"sourcesContent":["import { type HTMLAttributes, type ReactNode, createContext, use, useState } from 'react';\nimport { I18nProvider } from 'react-aria-components';\nimport { IntlContext, IntlProvider, type IntlShape } from 'react-intl';\n\nimport { getPanneauMessages } from '@panneau/intl';\n\nimport { type ColorScheme, type Theme, getThemeCss, hashString } from '../theme/theme';\nimport { ToastProvider } from '../toast/Toast';\nimport { cx } from '../utils/cx';\nimport styles from './PanneauRoot.module.css';\n\nexport interface PanneauRootProps extends HTMLAttributes<HTMLDivElement> {\n /** Tokens that override the default theme: `bootstrapTheme`, or a project's own. */\n theme?: Theme | null;\n /** Defaults to `light`. `auto` follows the system setting. */\n colorScheme?: ColorScheme;\n /**\n * Locale of dates and numbers in React Aria components. Defaults to the react-intl locale, or\n * to the browser's without an `IntlProvider`.\n *\n * Without an `IntlProvider` above it, the root provides one, with the messages of every Panneau\n * package in this locale (English without a locale, or for a locale Panneau doesn't translate).\n * An app with its own `IntlProvider` adds them with `withPanneauMessages()` from\n * `@panneau/intl`.\n */\n locale?: string;\n children?: ReactNode;\n}\n\n/** `undefined` outside of a root, `null` while the root's container isn't mounted yet. */\nconst PortalContext = createContext<Element | null | undefined>(undefined);\n\n/**\n * The element overlays render into: the closest `PanneauRoot`'s, or `undefined` for the body\n * without a root. It is `null` during the first render of a root: overlays wait for it, since\n * React Aria hides everything outside of a modal from assistive technologies when it opens.\n */\nexport function usePortalContainer(): Element | null | undefined {\n return use(PortalContext);\n}\n\n/**\n * An `IntlProvider` with Panneau's messages in a locale, for a root without one above it. A locale\n * Panneau doesn't translate gets English, so that react-intl doesn't report every message as\n * missing.\n */\nfunction PanneauIntlProvider({\n locale = 'en',\n children,\n}: {\n locale?: string;\n children: ReactNode;\n}) {\n const messages = getPanneauMessages(locale);\n const translated = Object.keys(messages).length > 0;\n return (\n <IntlProvider\n locale={translated ? locale : 'en'}\n defaultLocale=\"en\"\n messages={translated ? messages : getPanneauMessages('en')}\n >\n {children}\n </IntlProvider>\n );\n}\n\n/**\n * The root of every Panneau interface. It scopes the base stylesheet and the design tokens to its\n * element (no global CSS), applies a theme and a color scheme, and hosts overlays and toasts so\n * that they get the tokens too. Panneau components must render inside one. A project can override\n * any token with its own class on the root. Without an `IntlProvider` above it, it provides one\n * with Panneau's messages in its `locale`.\n */\nexport function PanneauRoot({\n theme = null,\n colorScheme = 'light',\n locale,\n className,\n children,\n ...props\n}: PanneauRootProps) {\n const intl = use(IntlContext) as IntlShape | null | undefined;\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const css = theme !== null ? getThemeCss(theme, '§') : '';\n const scope = css !== '' ? hashString(css) : undefined;\n const root = (\n <div\n {...props}\n className={cx(styles.root, className)}\n data-color-scheme={colorScheme}\n data-panneau-theme={scope}\n >\n {scope !== undefined ? (\n <style href={`panneau-theme-${scope}`} precedence=\"panneau\">\n {css.replaceAll('§', scope)}\n </style>\n ) : null}\n <I18nProvider locale={locale ?? intl?.locale}>\n <PortalContext value={container}>\n <ToastProvider\n regionClassName={styles.root}\n regionProps={{\n 'data-color-scheme': colorScheme,\n 'data-panneau-theme': scope,\n }}\n >\n {children}\n </ToastProvider>\n </PortalContext>\n <div ref={setContainer} className={styles.portal} />\n </I18nProvider>\n </div>\n );\n if (intl === null || intl === undefined) {\n return <PanneauIntlProvider locale={locale}>{root}</PanneauIntlProvider>;\n }\n return root;\n}\n"],"mappings":";;;;;;;;;;;AA8BA,IAAM,gBAAgB,cAA0C,KAAA,CAAS;;;;;;AAOzE,SAAgB,qBAAiD;CAC7D,OAAO,IAAI,aAAa;AAC5B;;;;;;AAOA,SAAS,oBAAoB,EACzB,SAAS,MACT,YAID;CACC,MAAM,WAAW,mBAAmB,MAAM;CAC1C,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS;CAClD,OACI,oBAAC,cAAD;EACI,QAAQ,aAAa,SAAS;EAC9B,eAAc;EACd,UAAU,aAAa,WAAW,mBAAmB,IAAI;EAExD;CACS,CAAA;AAEtB;;;;;;;;AASA,SAAgB,YAAY,EACxB,QAAQ,MACR,cAAc,SACd,QACA,WACA,UACA,GAAG,SACc;CACjB,MAAM,OAAO,IAAI,WAAW;CAC5B,MAAM,CAAC,WAAW,gBAAgB,SAAgC,IAAI;CACtE,MAAM,MAAM,UAAU,OAAO,YAAY,OAAO,GAAG,IAAI;CACvD,MAAM,QAAQ,QAAQ,KAAK,WAAW,GAAG,IAAI,KAAA;CAC7C,MAAM,OACF,qBAAC,OAAD;EACI,GAAI;EACJ,WAAW,GAAGA,2BAAO,MAAM,SAAS;EACpC,qBAAmB;EACnB,sBAAoB;EAJxB,UAAA,CAMK,UAAU,KAAA,IACP,oBAAC,SAAD;GAAO,MAAM,iBAAiB;GAAS,YAAW;GAC7C,UAAA,IAAI,WAAW,KAAK,KAAK;EACvB,CAAA,IACP,MACJ,qBAAC,cAAD;GAAc,QAAQ,UAAU,MAAM;GAAtC,UAAA,CACI,oBAAC,eAAD;IAAe,OAAO;IAClB,UAAA,oBAAC,eAAD;KACI,iBAAiBA,2BAAO;KACxB,aAAa;MACT,qBAAqB;MACrB,sBAAsB;KAC1B;KAEC;IACU,CAAA;GACJ,CAAA,GACf,oBAAC,OAAD;IAAK,KAAK;IAAc,WAAWA,2BAAO;GAAO,CAAA,CACvC;EACb,CAAA,CAAA;;CAET,IAAI,SAAS,QAAQ,SAAS,KAAA,GAC1B,OAAO,oBAAC,qBAAD;EAA6B;EAAS,UAAA;CAA0B,CAAA;CAE3E,OAAO;AACX"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "./PanneauRoot.css";
|
|
2
|
+
//#region src/root/PanneauRoot.module.css
|
|
3
|
+
var root = "panneau-root--wA35w";
|
|
4
|
+
var portal = "panneau-portal-keLcJN";
|
|
5
|
+
var PanneauRoot_module_default = {
|
|
6
|
+
root,
|
|
7
|
+
portal
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { PanneauRoot_module_default as default, portal, root };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=PanneauRoot.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanneauRoot.module.js","names":[],"sources":["../../src/root/PanneauRoot.module.css"],"sourcesContent":["/*\n * Design tokens of the default theme, and the base stylesheet of Panneau. Everything is scoped to\n * the root element: nothing here applies outside of it (decision 0005).\n *\n * Defaults are wrapped in :where() so that they have no specificity: a theme, or a project's own\n * class on the root, overrides any token without fighting the cascade.\n */\n\n:where(.root) {\n /* Surfaces */\n --panneau-color-bg: #ffffff;\n --panneau-color-surface: #ffffff;\n --panneau-color-surface-sunken: #f4f4f5;\n --panneau-color-surface-raised: #ffffff;\n --panneau-color-hover: rgb(24 24 27 / 0.06);\n --panneau-color-pressed: rgb(24 24 27 / 0.1);\n --panneau-color-backdrop: rgb(9 9 11 / 0.45);\n\n /* Text */\n --panneau-color-text: #18181b;\n --panneau-color-text-muted: #52525b;\n --panneau-color-link: #1d4ed8;\n\n /* Borders: separators, and the outline of controls (3:1 against the surface) */\n --panneau-color-border: #e4e4e7;\n --panneau-color-border-control: #8b8b94;\n\n /* Accent: primary buttons, checked controls, selection */\n --panneau-color-accent: #18181b;\n --panneau-color-accent-hover: #3f3f46;\n --panneau-color-accent-text: #ffffff;\n --panneau-color-accent-subtle: #f4f4f5;\n --panneau-color-focus: #2563eb;\n\n /* Tones: text on surfaces, subtle backgrounds, borders */\n --panneau-color-danger: #b91c1c;\n --panneau-color-danger-subtle: #fef2f2;\n --panneau-color-danger-border: #fca5a5;\n --panneau-color-danger-solid: #b91c1c;\n --panneau-color-danger-solid-hover: #991b1b;\n --panneau-color-danger-solid-text: #ffffff;\n --panneau-color-success: #15803d;\n --panneau-color-success-subtle: #f0fdf4;\n --panneau-color-success-border: #86efac;\n --panneau-color-warning: #a16207;\n --panneau-color-warning-subtle: #fefce8;\n --panneau-color-warning-border: #fcd34d;\n --panneau-color-info: #1d4ed8;\n --panneau-color-info-subtle: #eff6ff;\n --panneau-color-info-border: #93c5fd;\n\n /* Typography */\n --panneau-font-family:\n system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --panneau-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n --panneau-font-size-xs: 0.75rem;\n --panneau-font-size-sm: 0.8125rem;\n --panneau-font-size-md: 0.875rem;\n --panneau-font-size-lg: 1rem;\n --panneau-font-size-xl: 1.25rem;\n --panneau-font-size-control: 0.875rem;\n --panneau-line-height: 1.5;\n --panneau-line-height-tight: 1.25;\n --panneau-font-weight-normal: 400;\n --panneau-font-weight-medium: 500;\n --panneau-font-weight-bold: 600;\n\n /* Spacing, on a 4px scale */\n --panneau-space-1: 0.25rem;\n --panneau-space-2: 0.5rem;\n --panneau-space-3: 0.75rem;\n --panneau-space-4: 1rem;\n --panneau-space-5: 1.25rem;\n --panneau-space-6: 1.5rem;\n --panneau-space-8: 2rem;\n --panneau-space-10: 2.5rem;\n\n /* Shapes */\n --panneau-radius-sm: 0.25rem;\n --panneau-radius-md: 0.375rem;\n --panneau-radius-lg: 0.5rem;\n --panneau-radius-full: 9999px;\n --panneau-border-width: 1px;\n --panneau-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.06);\n --panneau-shadow-md: 0 1px 3px rgb(0 0 0 / 0.08), 0 4px 12px rgb(0 0 0 / 0.08);\n --panneau-shadow-lg: 0 4px 8px rgb(0 0 0 / 0.08), 0 16px 40px rgb(0 0 0 / 0.16);\n\n /* Controls */\n --panneau-control-height: 2.25rem;\n --panneau-control-height-sm: 1.875rem;\n --panneau-focus-width: 2px;\n\n /* Motion and layers */\n --panneau-duration: 150ms;\n --panneau-z-overlay: 1000;\n --panneau-z-toast: 1100;\n\n color-scheme: light;\n}\n\n:where(.root[data-color-scheme='dark']) {\n --panneau-color-bg: #09090b;\n --panneau-color-surface: #18181b;\n --panneau-color-surface-sunken: #111113;\n --panneau-color-surface-raised: #232326;\n --panneau-color-hover: rgb(255 255 255 / 0.07);\n --panneau-color-pressed: rgb(255 255 255 / 0.12);\n --panneau-color-backdrop: rgb(0 0 0 / 0.6);\n --panneau-color-text: #fafafa;\n --panneau-color-text-muted: #a1a1aa;\n --panneau-color-link: #93c5fd;\n --panneau-color-border: #2e2e33;\n --panneau-color-border-control: #71717a;\n --panneau-color-accent: #fafafa;\n --panneau-color-accent-hover: #d4d4d8;\n --panneau-color-accent-text: #18181b;\n --panneau-color-accent-subtle: #2e2e33;\n --panneau-color-focus: #60a5fa;\n --panneau-color-danger: #fca5a5;\n --panneau-color-danger-subtle: rgb(127 29 29 / 0.35);\n --panneau-color-danger-border: #b91c1c;\n --panneau-color-danger-solid: #dc2626;\n --panneau-color-danger-solid-hover: #b91c1c;\n --panneau-color-danger-solid-text: #ffffff;\n --panneau-color-success: #86efac;\n --panneau-color-success-subtle: rgb(20 83 45 / 0.35);\n --panneau-color-success-border: #15803d;\n --panneau-color-warning: #fcd34d;\n --panneau-color-warning-subtle: rgb(113 63 18 / 0.35);\n --panneau-color-warning-border: #a16207;\n --panneau-color-info: #93c5fd;\n --panneau-color-info-subtle: rgb(30 58 138 / 0.35);\n --panneau-color-info-border: #1d4ed8;\n --panneau-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.4);\n --panneau-shadow-md: 0 1px 3px rgb(0 0 0 / 0.4), 0 4px 12px rgb(0 0 0 / 0.4);\n --panneau-shadow-lg: 0 4px 8px rgb(0 0 0 / 0.4), 0 16px 40px rgb(0 0 0 / 0.5);\n\n color-scheme: dark;\n}\n\n@media (prefers-color-scheme: dark) {\n :where(.root[data-color-scheme='auto']) {\n --panneau-color-bg: #09090b;\n --panneau-color-surface: #18181b;\n --panneau-color-surface-sunken: #111113;\n --panneau-color-surface-raised: #232326;\n --panneau-color-hover: rgb(255 255 255 / 0.07);\n --panneau-color-pressed: rgb(255 255 255 / 0.12);\n --panneau-color-backdrop: rgb(0 0 0 / 0.6);\n --panneau-color-text: #fafafa;\n --panneau-color-text-muted: #a1a1aa;\n --panneau-color-link: #93c5fd;\n --panneau-color-border: #2e2e33;\n --panneau-color-border-control: #71717a;\n --panneau-color-accent: #fafafa;\n --panneau-color-accent-hover: #d4d4d8;\n --panneau-color-accent-text: #18181b;\n --panneau-color-accent-subtle: #2e2e33;\n --panneau-color-focus: #60a5fa;\n --panneau-color-danger: #fca5a5;\n --panneau-color-danger-subtle: rgb(127 29 29 / 0.35);\n --panneau-color-danger-border: #b91c1c;\n --panneau-color-danger-solid: #dc2626;\n --panneau-color-danger-solid-hover: #b91c1c;\n --panneau-color-danger-solid-text: #ffffff;\n --panneau-color-success: #86efac;\n --panneau-color-success-subtle: rgb(20 83 45 / 0.35);\n --panneau-color-success-border: #15803d;\n --panneau-color-warning: #fcd34d;\n --panneau-color-warning-subtle: rgb(113 63 18 / 0.35);\n --panneau-color-warning-border: #a16207;\n --panneau-color-info: #93c5fd;\n --panneau-color-info-subtle: rgb(30 58 138 / 0.35);\n --panneau-color-info-border: #1d4ed8;\n --panneau-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.4);\n --panneau-shadow-md: 0 1px 3px rgb(0 0 0 / 0.4), 0 4px 12px rgb(0 0 0 / 0.4);\n --panneau-shadow-lg: 0 4px 8px rgb(0 0 0 / 0.4), 0 16px 40px rgb(0 0 0 / 0.5);\n\n color-scheme: dark;\n }\n}\n\n/* Touch screens: larger targets, and 16px text in inputs so that iOS doesn't zoom on focus. */\n@media (pointer: coarse) {\n :where(.root) {\n --panneau-control-height: 2.75rem;\n --panneau-control-height-sm: 2.25rem;\n --panneau-font-size-control: 1rem;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :where(.root) {\n --panneau-duration: 0ms;\n }\n}\n\n/* Base stylesheet, scoped to the root, without specificity: components and projects override it. */\n\n.root {\n /* The class is mostly a hook for the rules below, which use :where(). */\n display: block;\n}\n\n:where(.root) {\n font-family: var(--panneau-font-family);\n font-size: var(--panneau-font-size-md);\n line-height: var(--panneau-line-height);\n color: var(--panneau-color-text);\n background-color: var(--panneau-color-bg);\n -webkit-font-smoothing: antialiased;\n -webkit-text-size-adjust: 100%;\n text-size-adjust: 100%;\n}\n\n:where(.root) :where(*, *::before, *::after) {\n box-sizing: border-box;\n}\n\n:where(.root) :where(h1, h2, h3, h4, h5, h6, p, ul, ol, dl, figure, fieldset, legend) {\n margin: 0;\n padding: 0;\n}\n\n:where(.root) :where(fieldset) {\n border: 0;\n min-width: 0;\n}\n\n:where(.root) :where(button, input, select, textarea) {\n font: inherit;\n color: inherit;\n}\n\n:where(.root) :where(a) {\n color: var(--panneau-color-link);\n}\n\n:where(.root) :where(img, svg, video) {\n max-width: 100%;\n}\n\n:where(.root) :where(:focus-visible) {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 2px;\n}\n\n/* Overlays (dialogs, popovers, menus, tooltips) render here, so that they get the tokens. */\n.portal {\n display: contents;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/* Options of selects, combo boxes and menus. */
|
|
2
|
+
|
|
3
|
+
.panneau-listBox-8esRuh {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
max-height: inherit;
|
|
7
|
+
padding: var(--panneau-space-1);
|
|
8
|
+
overflow: auto;
|
|
9
|
+
outline: none;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.panneau-item-Zfuva9 {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
gap: var(--panneau-space-2);
|
|
16
|
+
min-height: var(--panneau-control-height-sm);
|
|
17
|
+
padding: var(--panneau-space-1) var(--panneau-space-2);
|
|
18
|
+
font-size: var(--panneau-font-size-control);
|
|
19
|
+
line-height: var(--panneau-line-height-tight);
|
|
20
|
+
color: var(--panneau-color-text);
|
|
21
|
+
cursor: default;
|
|
22
|
+
border-radius: var(--panneau-radius-sm);
|
|
23
|
+
outline: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.panneau-item-Zfuva9[data-focused],
|
|
27
|
+
.panneau-item-Zfuva9[data-hovered] {
|
|
28
|
+
background-color: var(--panneau-color-hover);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.panneau-item-Zfuva9[data-focus-visible] {
|
|
32
|
+
outline: var(--panneau-focus-width) solid var(--panneau-color-focus);
|
|
33
|
+
outline-offset: -2px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.panneau-item-Zfuva9[data-disabled] {
|
|
37
|
+
cursor: not-allowed;
|
|
38
|
+
opacity: 0.5;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.panneau-item-Zfuva9[data-danger] {
|
|
42
|
+
color: var(--panneau-color-danger);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.panneau-itemText-P7FtjI {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex: 1 1 auto;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
min-width: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.panneau-itemLabel-nLMoU0 {
|
|
53
|
+
overflow-wrap: anywhere;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.panneau-itemDescription--u64pt {
|
|
57
|
+
font-size: var(--panneau-font-size-sm);
|
|
58
|
+
color: var(--panneau-color-text-muted);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.panneau-check-o1OMYv {
|
|
62
|
+
flex: 0 0 auto;
|
|
63
|
+
width: 1rem;
|
|
64
|
+
color: var(--panneau-color-text);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.panneau-placeholder-Ln7J3j {
|
|
68
|
+
color: var(--panneau-color-text-muted);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.panneau-empty-4GCKMh {
|
|
72
|
+
padding: var(--panneau-space-2);
|
|
73
|
+
font-size: var(--panneau-font-size-sm);
|
|
74
|
+
color: var(--panneau-color-text-muted);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.panneau-separator-FjQdQ6 {
|
|
78
|
+
height: 1px;
|
|
79
|
+
margin: var(--panneau-space-1) 0;
|
|
80
|
+
background-color: var(--panneau-color-border);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.panneau-trigger-3OeZeM {
|
|
84
|
+
justify-content: space-between;
|
|
85
|
+
gap: var(--panneau-space-2);
|
|
86
|
+
text-align: start;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.panneau-value-J-b74F {
|
|
91
|
+
flex: 1 1 auto;
|
|
92
|
+
min-width: 0;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
text-overflow: ellipsis;
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.panneau-value-J-b74F[data-placeholder] {
|
|
99
|
+
color: var(--panneau-color-text-muted);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.panneau-chevron-w-papm {
|
|
103
|
+
color: var(--panneau-color-text-muted);
|
|
104
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import "./ListBox.css";
|
|
2
|
+
//#region src/select/ListBox.module.css
|
|
3
|
+
var listBox = "panneau-listBox-8esRuh";
|
|
4
|
+
var item = "panneau-item-Zfuva9";
|
|
5
|
+
var itemText = "panneau-itemText-P7FtjI";
|
|
6
|
+
var itemLabel = "panneau-itemLabel-nLMoU0";
|
|
7
|
+
var itemDescription = "panneau-itemDescription--u64pt";
|
|
8
|
+
var check = "panneau-check-o1OMYv";
|
|
9
|
+
var placeholder = "panneau-placeholder-Ln7J3j";
|
|
10
|
+
var empty = "panneau-empty-4GCKMh";
|
|
11
|
+
var separator = "panneau-separator-FjQdQ6";
|
|
12
|
+
var trigger = "panneau-trigger-3OeZeM";
|
|
13
|
+
var value = "panneau-value-J-b74F";
|
|
14
|
+
var chevron = "panneau-chevron-w-papm";
|
|
15
|
+
var ListBox_module_default = {
|
|
16
|
+
listBox,
|
|
17
|
+
item,
|
|
18
|
+
itemText,
|
|
19
|
+
itemLabel,
|
|
20
|
+
itemDescription,
|
|
21
|
+
check,
|
|
22
|
+
placeholder,
|
|
23
|
+
empty,
|
|
24
|
+
separator,
|
|
25
|
+
trigger,
|
|
26
|
+
value,
|
|
27
|
+
chevron
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { check, chevron, ListBox_module_default as default, empty, item, itemDescription, itemLabel, itemText, listBox, placeholder, separator, trigger, value };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=ListBox.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListBox.module.js","names":[],"sources":["../../src/select/ListBox.module.css"],"sourcesContent":["/* Options of selects, combo boxes and menus. */\n\n.listBox {\n display: flex;\n flex-direction: column;\n max-height: inherit;\n padding: var(--panneau-space-1);\n overflow: auto;\n outline: none;\n}\n\n.item {\n display: flex;\n align-items: center;\n gap: var(--panneau-space-2);\n min-height: var(--panneau-control-height-sm);\n padding: var(--panneau-space-1) var(--panneau-space-2);\n font-size: var(--panneau-font-size-control);\n line-height: var(--panneau-line-height-tight);\n color: var(--panneau-color-text);\n cursor: default;\n border-radius: var(--panneau-radius-sm);\n outline: none;\n}\n\n.item[data-focused],\n.item[data-hovered] {\n background-color: var(--panneau-color-hover);\n}\n\n.item[data-focus-visible] {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: -2px;\n}\n\n.item[data-disabled] {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.item[data-danger] {\n color: var(--panneau-color-danger);\n}\n\n.itemText {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n}\n\n.itemLabel {\n overflow-wrap: anywhere;\n}\n\n.itemDescription {\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n}\n\n.check {\n flex: 0 0 auto;\n width: 1rem;\n color: var(--panneau-color-text);\n}\n\n.placeholder {\n color: var(--panneau-color-text-muted);\n}\n\n.empty {\n padding: var(--panneau-space-2);\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n}\n\n.separator {\n height: 1px;\n margin: var(--panneau-space-1) 0;\n background-color: var(--panneau-color-border);\n}\n\n.trigger {\n justify-content: space-between;\n gap: var(--panneau-space-2);\n text-align: start;\n cursor: pointer;\n}\n\n.value {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value[data-placeholder] {\n color: var(--panneau-color-text-muted);\n}\n\n.chevron {\n color: var(--panneau-color-text-muted);\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type FieldChromeProps } from '../field/FieldParts';
|
|
2
|
+
/** The value of an option. */
|
|
3
|
+
export type OptionValue = string | number | boolean;
|
|
4
|
+
/** A choice of a select, a radio group or a combo box. Same shape as the protocol's `Option`. */
|
|
5
|
+
export interface SelectOption {
|
|
6
|
+
value: OptionValue;
|
|
7
|
+
label: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Props of both single and multiple selects. */
|
|
12
|
+
export interface SelectBaseProps extends FieldChromeProps {
|
|
13
|
+
options: readonly SelectOption[];
|
|
14
|
+
/** Text shown without a value. Defaults to "Select…". */
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
isRequired?: boolean;
|
|
17
|
+
isDisabled?: boolean;
|
|
18
|
+
name?: string;
|
|
19
|
+
autoFocus?: boolean;
|
|
20
|
+
onBlur?: () => void;
|
|
21
|
+
'aria-label'?: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
/** Class name of the button that opens the options. */
|
|
24
|
+
triggerClassName?: string;
|
|
25
|
+
popoverClassName?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface SingleSelectProps extends SelectBaseProps {
|
|
28
|
+
multiple?: false;
|
|
29
|
+
/** The selected value, or `null`. */
|
|
30
|
+
value?: OptionValue | null;
|
|
31
|
+
onChange?: (value: OptionValue | null) => void;
|
|
32
|
+
}
|
|
33
|
+
export interface MultipleSelectProps extends SelectBaseProps {
|
|
34
|
+
/** Several values can be selected. */
|
|
35
|
+
multiple: true;
|
|
36
|
+
value?: readonly OptionValue[];
|
|
37
|
+
onChange?: (value: OptionValue[]) => void;
|
|
38
|
+
}
|
|
39
|
+
export type SelectProps = SingleSelectProps | MultipleSelectProps;
|
|
40
|
+
/**
|
|
41
|
+
* A dropdown to pick one option, or several with `multiple`. Option values can be strings,
|
|
42
|
+
* numbers or booleans. Unless `isRequired`, a single select has an empty choice first.
|
|
43
|
+
*/
|
|
44
|
+
export declare function Select(props: SelectProps): import("react").JSX.Element;
|
|
45
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/select/Select.tsx"],"names":[],"mappings":"AAWA,OAAO,EACH,KAAK,gBAAgB,EAKxB,MAAM,qBAAqB,CAAC;AAQ7B,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,iGAAiG;AACjG,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACrD,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACtD,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,qCAAqC;IACrC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IACxD,sCAAsC;IACtC,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;CAC7C;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;AAgBlE;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,+BAsIxC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { cx } from "../utils/cx.js";
|
|
2
|
+
import { Icon } from "../icon/Icon.js";
|
|
3
|
+
import { messages } from "../intl/messages.js";
|
|
4
|
+
import { usePanneauIntl } from "../intl/usePanneauIntl.js";
|
|
5
|
+
import Field_module_default from "../field/Field.module.js";
|
|
6
|
+
import { FieldDescription, FieldErrors, FieldLabel } from "../field/FieldParts.js";
|
|
7
|
+
import { PopoverSurface } from "../popover/Popover.js";
|
|
8
|
+
import ListBox_module_default from "./ListBox.module.js";
|
|
9
|
+
import { Check, ChevronDown } from "lucide-react";
|
|
10
|
+
import { Button, ListBox, ListBoxItem, Select, SelectValue, Text } from "react-aria-components";
|
|
11
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
//#region src/select/Select.tsx
|
|
13
|
+
var EMPTY_KEY = "__panneau_empty__";
|
|
14
|
+
function keyOf(options, value) {
|
|
15
|
+
const index = options.findIndex((option) => option.value === value);
|
|
16
|
+
return index === -1 ? null : String(index);
|
|
17
|
+
}
|
|
18
|
+
function valueOf(options, key) {
|
|
19
|
+
if (key === null || key === EMPTY_KEY) return null;
|
|
20
|
+
return options[Number(key)]?.value ?? null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A dropdown to pick one option, or several with `multiple`. Option values can be strings,
|
|
24
|
+
* numbers or booleans. Unless `isRequired`, a single select has an empty choice first.
|
|
25
|
+
*/
|
|
26
|
+
function Select$1(props) {
|
|
27
|
+
const intl = usePanneauIntl();
|
|
28
|
+
const { options, label, description, errors = [], placeholder = intl.formatMessage(messages.selectPlaceholder), isRequired = false, isDisabled, name, autoFocus, onBlur, id, className, labelClassName, descriptionClassName, errorsClassName, triggerClassName, popoverClassName } = props;
|
|
29
|
+
const invalid = errors.length > 0;
|
|
30
|
+
const items = options.map((option, index) => ({
|
|
31
|
+
...option,
|
|
32
|
+
key: String(index)
|
|
33
|
+
}));
|
|
34
|
+
const withEmpty = props.multiple !== true && !isRequired;
|
|
35
|
+
const shared = {
|
|
36
|
+
id,
|
|
37
|
+
name,
|
|
38
|
+
autoFocus,
|
|
39
|
+
isDisabled,
|
|
40
|
+
isRequired,
|
|
41
|
+
isInvalid: invalid,
|
|
42
|
+
placeholder,
|
|
43
|
+
"aria-label": props["aria-label"],
|
|
44
|
+
validationBehavior: "aria",
|
|
45
|
+
onBlur: onBlur !== void 0 ? () => onBlur() : void 0,
|
|
46
|
+
disabledKeys: items.filter((item) => item.disabled === true).map((item_0) => item_0.key),
|
|
47
|
+
className: cx(Field_module_default.field, className)
|
|
48
|
+
};
|
|
49
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
50
|
+
/* @__PURE__ */ jsx(FieldLabel, {
|
|
51
|
+
isRequired,
|
|
52
|
+
className: labelClassName,
|
|
53
|
+
children: label
|
|
54
|
+
}),
|
|
55
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
56
|
+
className: cx(Field_module_default.control, ListBox_module_default.trigger, triggerClassName),
|
|
57
|
+
children: [/* @__PURE__ */ jsx(SelectValue, { className: ListBox_module_default.value }), /* @__PURE__ */ jsx(Icon, {
|
|
58
|
+
icon: ChevronDown,
|
|
59
|
+
className: ListBox_module_default.chevron
|
|
60
|
+
})]
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ jsx(FieldDescription, {
|
|
63
|
+
className: descriptionClassName,
|
|
64
|
+
children: description
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ jsx(FieldErrors, {
|
|
67
|
+
errors,
|
|
68
|
+
className: errorsClassName
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ jsx(PopoverSurface, {
|
|
71
|
+
className: popoverClassName,
|
|
72
|
+
children: /* @__PURE__ */ jsxs(ListBox, {
|
|
73
|
+
className: ListBox_module_default.listBox,
|
|
74
|
+
children: [withEmpty ? /* @__PURE__ */ jsxs(ListBoxItem, {
|
|
75
|
+
id: EMPTY_KEY,
|
|
76
|
+
textValue: placeholder,
|
|
77
|
+
className: ListBox_module_default.item,
|
|
78
|
+
children: [/* @__PURE__ */ jsx("span", { className: ListBox_module_default.check }), /* @__PURE__ */ jsx("span", {
|
|
79
|
+
className: ListBox_module_default.placeholder,
|
|
80
|
+
children: placeholder
|
|
81
|
+
})]
|
|
82
|
+
}) : null, items.map((item_1) => /* @__PURE__ */ jsx(ListBoxItem, {
|
|
83
|
+
id: item_1.key,
|
|
84
|
+
textValue: item_1.label,
|
|
85
|
+
className: ListBox_module_default.item,
|
|
86
|
+
children: ({ isSelected }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
87
|
+
className: ListBox_module_default.check,
|
|
88
|
+
children: isSelected ? /* @__PURE__ */ jsx(Icon, {
|
|
89
|
+
icon: Check,
|
|
90
|
+
size: "sm"
|
|
91
|
+
}) : null
|
|
92
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
93
|
+
className: ListBox_module_default.itemText,
|
|
94
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
95
|
+
slot: "label",
|
|
96
|
+
className: ListBox_module_default.itemLabel,
|
|
97
|
+
children: item_1.label
|
|
98
|
+
}), item_1.description !== void 0 ? /* @__PURE__ */ jsx(Text, {
|
|
99
|
+
slot: "description",
|
|
100
|
+
className: ListBox_module_default.itemDescription,
|
|
101
|
+
children: item_1.description
|
|
102
|
+
}) : null]
|
|
103
|
+
})] })
|
|
104
|
+
}, item_1.key))]
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
] });
|
|
108
|
+
if (props.multiple === true) {
|
|
109
|
+
const { value, onChange } = props;
|
|
110
|
+
return /* @__PURE__ */ jsx(Select, {
|
|
111
|
+
...shared,
|
|
112
|
+
selectionMode: "multiple",
|
|
113
|
+
value: value !== void 0 ? value.flatMap((item_2) => {
|
|
114
|
+
const key = keyOf(options, item_2);
|
|
115
|
+
return key !== null ? [key] : [];
|
|
116
|
+
}) : void 0,
|
|
117
|
+
onChange: (keys) => onChange?.(keys.flatMap((key_0) => {
|
|
118
|
+
const item_3 = valueOf(options, key_0);
|
|
119
|
+
return item_3 !== null ? [item_3] : [];
|
|
120
|
+
})),
|
|
121
|
+
children: content
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const { value: value_0, onChange: onChange_0 } = props;
|
|
125
|
+
return /* @__PURE__ */ jsx(Select, {
|
|
126
|
+
...shared,
|
|
127
|
+
selectionMode: "single",
|
|
128
|
+
value: value_0 !== void 0 ? value_0 !== null ? keyOf(options, value_0) : null : void 0,
|
|
129
|
+
onChange: (key_1) => onChange_0?.(valueOf(options, key_1)),
|
|
130
|
+
children: content
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
134
|
+
export { Select$1 as Select };
|
|
135
|
+
|
|
136
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","names":["item","key","value","onChange","Select","fieldStyles","_Fragment","styles","AriaSelect"],"sources":["../../src/select/Select.tsx"],"sourcesContent":["import { Check, ChevronDown } from 'lucide-react';\nimport type { Key } from 'react-aria-components';\nimport {\n Select as AriaSelect,\n Button,\n ListBox,\n ListBoxItem,\n SelectValue,\n Text,\n} from 'react-aria-components';\n\nimport {\n type FieldChromeProps,\n FieldDescription,\n FieldErrors,\n FieldLabel,\n fieldStyles,\n} from '../field/FieldParts';\nimport { Icon } from '../icon/Icon';\nimport { messages } from '../intl/messages';\nimport { usePanneauIntl } from '../intl/usePanneauIntl';\nimport { PopoverSurface } from '../popover/Popover';\nimport { cx } from '../utils/cx';\nimport styles from './ListBox.module.css';\n\n/** The value of an option. */\nexport type OptionValue = string | number | boolean;\n\n/** A choice of a select, a radio group or a combo box. Same shape as the protocol's `Option`. */\nexport interface SelectOption {\n value: OptionValue;\n label: string;\n description?: string;\n disabled?: boolean;\n}\n\n/** Props of both single and multiple selects. */\nexport interface SelectBaseProps extends FieldChromeProps {\n options: readonly SelectOption[];\n /** Text shown without a value. Defaults to \"Select…\". */\n placeholder?: string;\n isRequired?: boolean;\n isDisabled?: boolean;\n name?: string;\n autoFocus?: boolean;\n onBlur?: () => void;\n 'aria-label'?: string;\n id?: string;\n /** Class name of the button that opens the options. */\n triggerClassName?: string;\n popoverClassName?: string;\n}\n\nexport interface SingleSelectProps extends SelectBaseProps {\n multiple?: false;\n /** The selected value, or `null`. */\n value?: OptionValue | null;\n onChange?: (value: OptionValue | null) => void;\n}\n\nexport interface MultipleSelectProps extends SelectBaseProps {\n /** Several values can be selected. */\n multiple: true;\n value?: readonly OptionValue[];\n onChange?: (value: OptionValue[]) => void;\n}\n\nexport type SelectProps = SingleSelectProps | MultipleSelectProps;\n\nconst EMPTY_KEY = '__panneau_empty__';\n\nfunction keyOf(options: readonly SelectOption[], value: OptionValue): Key | null {\n const index = options.findIndex((option) => option.value === value);\n return index === -1 ? null : String(index);\n}\n\nfunction valueOf(options: readonly SelectOption[], key: Key | null): OptionValue | null {\n if (key === null || key === EMPTY_KEY) {\n return null;\n }\n return options[Number(key)]?.value ?? null;\n}\n\n/**\n * A dropdown to pick one option, or several with `multiple`. Option values can be strings,\n * numbers or booleans. Unless `isRequired`, a single select has an empty choice first.\n */\nexport function Select(props: SelectProps) {\n const intl = usePanneauIntl();\n const {\n options,\n label,\n description,\n errors = [],\n placeholder = intl.formatMessage(messages.selectPlaceholder),\n isRequired = false,\n isDisabled,\n name,\n autoFocus,\n onBlur,\n id,\n className,\n labelClassName,\n descriptionClassName,\n errorsClassName,\n triggerClassName,\n popoverClassName,\n } = props;\n const invalid = errors.length > 0;\n const items = options.map((option, index) => ({ ...option, key: String(index) }));\n const withEmpty = props.multiple !== true && !isRequired;\n\n const shared = {\n id,\n name,\n autoFocus,\n isDisabled,\n isRequired,\n isInvalid: invalid,\n placeholder,\n 'aria-label': props['aria-label'],\n validationBehavior: 'aria' as const,\n onBlur: onBlur !== undefined ? () => onBlur() : undefined,\n disabledKeys: items.filter((item) => item.disabled === true).map((item) => item.key),\n className: cx(fieldStyles.field, className),\n };\n\n const content = (\n <>\n <FieldLabel isRequired={isRequired} className={labelClassName}>\n {label}\n </FieldLabel>\n <Button className={cx(fieldStyles.control, styles.trigger, triggerClassName)}>\n <SelectValue className={styles.value} />\n <Icon icon={ChevronDown} className={styles.chevron} />\n </Button>\n <FieldDescription className={descriptionClassName}>{description}</FieldDescription>\n <FieldErrors errors={errors} className={errorsClassName} />\n <PopoverSurface className={popoverClassName}>\n <ListBox className={styles.listBox}>\n {withEmpty ? (\n <ListBoxItem id={EMPTY_KEY} textValue={placeholder} className={styles.item}>\n <span className={styles.check} />\n <span className={styles.placeholder}>{placeholder}</span>\n </ListBoxItem>\n ) : null}\n {items.map((item) => (\n <ListBoxItem\n key={item.key}\n id={item.key}\n textValue={item.label}\n className={styles.item}\n >\n {({ isSelected }) => (\n <>\n <span className={styles.check}>\n {isSelected ? <Icon icon={Check} size=\"sm\" /> : null}\n </span>\n <span className={styles.itemText}>\n <Text slot=\"label\" className={styles.itemLabel}>\n {item.label}\n </Text>\n {item.description !== undefined ? (\n <Text\n slot=\"description\"\n className={styles.itemDescription}\n >\n {item.description}\n </Text>\n ) : null}\n </span>\n </>\n )}\n </ListBoxItem>\n ))}\n </ListBox>\n </PopoverSurface>\n </>\n );\n\n if (props.multiple === true) {\n const { value, onChange } = props;\n return (\n <AriaSelect\n {...shared}\n selectionMode=\"multiple\"\n value={\n value !== undefined\n ? value.flatMap((item) => {\n const key = keyOf(options, item);\n return key !== null ? [key] : [];\n })\n : undefined\n }\n onChange={(keys) =>\n onChange?.(\n keys.flatMap((key) => {\n const item = valueOf(options, key);\n return item !== null ? [item] : [];\n }),\n )\n }\n >\n {content}\n </AriaSelect>\n );\n }\n\n const { value, onChange } = props;\n return (\n <AriaSelect\n {...shared}\n selectionMode=\"single\"\n value={\n value !== undefined ? (value !== null ? keyOf(options, value) : null) : undefined\n }\n onChange={(key) => onChange?.(valueOf(options, key))}\n >\n {content}\n </AriaSelect>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.panneau-spinner-iIx6pg {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: var(--panneau-space-2);
|
|
5
|
+
color: var(--panneau-color-text-muted);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.panneau-circle-A2p14W {
|
|
9
|
+
display: inline-block;
|
|
10
|
+
flex: 0 0 auto;
|
|
11
|
+
width: 1.25em;
|
|
12
|
+
height: 1.25em;
|
|
13
|
+
border: 2px solid currentColor;
|
|
14
|
+
border-right-color: transparent;
|
|
15
|
+
border-radius: var(--panneau-radius-full);
|
|
16
|
+
animation: panneau-spin-qVmYu0 0.7s linear infinite;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.panneau-sm-JoTrRC .panneau-circle-A2p14W {
|
|
20
|
+
width: 1em;
|
|
21
|
+
height: 1em;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.panneau-lg-PkO03p .panneau-circle-A2p14W {
|
|
25
|
+
width: 2em;
|
|
26
|
+
height: 2em;
|
|
27
|
+
border-width: 3px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@keyframes panneau-spin-qVmYu0 {
|
|
31
|
+
to {
|
|
32
|
+
transform: rotate(360deg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (prefers-reduced-motion: reduce) {
|
|
37
|
+
.panneau-circle-A2p14W {
|
|
38
|
+
animation-duration: 2s;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SpinnerProps {
|
|
2
|
+
/** Accessible label, and visible text with `showLabel`. Defaults to "Loading…". */
|
|
3
|
+
label?: string;
|
|
4
|
+
/** Shows the label next to the spinner. */
|
|
5
|
+
showLabel?: boolean;
|
|
6
|
+
size?: 'sm' | 'md' | 'lg';
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/** An indeterminate progress indicator, announced as loading. */
|
|
10
|
+
export declare function Spinner({ label, showLabel, size, className }: SpinnerProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=Spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/spinner/Spinner.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IACzB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,iEAAiE;AACjE,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAiB,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,YAAY,+BAazF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { cx } from "../utils/cx.js";
|
|
2
|
+
import { messages } from "../intl/messages.js";
|
|
3
|
+
import { usePanneauIntl } from "../intl/usePanneauIntl.js";
|
|
4
|
+
import Spinner_module_default from "./Spinner.module.js";
|
|
5
|
+
import { ProgressBar } from "react-aria-components";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/spinner/Spinner.tsx
|
|
8
|
+
/** An indeterminate progress indicator, announced as loading. */
|
|
9
|
+
function Spinner({ label, showLabel = false, size = "md", className }) {
|
|
10
|
+
const intl = usePanneauIntl();
|
|
11
|
+
const text = label ?? intl.formatMessage(messages.loading);
|
|
12
|
+
return /* @__PURE__ */ jsxs(ProgressBar, {
|
|
13
|
+
isIndeterminate: true,
|
|
14
|
+
"aria-label": text,
|
|
15
|
+
className: cx(Spinner_module_default.spinner, Spinner_module_default[size], className),
|
|
16
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
17
|
+
className: Spinner_module_default.circle,
|
|
18
|
+
"aria-hidden": "true"
|
|
19
|
+
}), showLabel ? /* @__PURE__ */ jsx("span", { children: text }) : null]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Spinner };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.js","names":["styles"],"sources":["../../src/spinner/Spinner.tsx"],"sourcesContent":["import { ProgressBar } from 'react-aria-components';\n\nimport { messages } from '../intl/messages';\nimport { usePanneauIntl } from '../intl/usePanneauIntl';\nimport { cx } from '../utils/cx';\nimport styles from './Spinner.module.css';\n\nexport interface SpinnerProps {\n /** Accessible label, and visible text with `showLabel`. Defaults to \"Loading…\". */\n label?: string;\n /** Shows the label next to the spinner. */\n showLabel?: boolean;\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n}\n\n/** An indeterminate progress indicator, announced as loading. */\nexport function Spinner({ label, showLabel = false, size = 'md', className }: SpinnerProps) {\n const intl = usePanneauIntl();\n const text = label ?? intl.formatMessage(messages.loading);\n return (\n <ProgressBar\n isIndeterminate\n aria-label={text}\n className={cx(styles.spinner, styles[size], className)}\n >\n <span className={styles.circle} aria-hidden=\"true\" />\n {showLabel ? <span>{text}</span> : null}\n </ProgressBar>\n );\n}\n"],"mappings":";;;;;;;;AAiBA,SAAgB,QAAQ,EAAE,OAAO,YAAY,OAAO,OAAO,MAAM,aAA2B;CACxF,MAAM,OAAO,eAAe;CAC5B,MAAM,OAAO,SAAS,KAAK,cAAc,SAAS,OAAO;CACzD,OACI,qBAAC,aAAD;EACI,iBAAA;EACA,cAAY;EACZ,WAAW,GAAGA,uBAAO,SAASA,uBAAO,OAAO,SAAS;EAHzD,UAAA,CAKI,oBAAC,QAAD;GAAM,WAAWA,uBAAO;GAAQ,eAAY;EAAM,CAAA,GACjD,YAAY,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA,IAAI,IAC1B;;AAErB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "./Spinner.css";
|
|
2
|
+
//#region src/spinner/Spinner.module.css
|
|
3
|
+
var spinner = "panneau-spinner-iIx6pg";
|
|
4
|
+
var circle = "panneau-circle-A2p14W";
|
|
5
|
+
var spin = "panneau-spin-qVmYu0";
|
|
6
|
+
var sm = "panneau-sm-JoTrRC";
|
|
7
|
+
var lg = "panneau-lg-PkO03p";
|
|
8
|
+
var Spinner_module_default = {
|
|
9
|
+
spinner,
|
|
10
|
+
circle,
|
|
11
|
+
spin,
|
|
12
|
+
sm,
|
|
13
|
+
lg
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { circle, Spinner_module_default as default, lg, sm, spin, spinner };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=Spinner.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.module.js","names":[],"sources":["../../src/spinner/Spinner.module.css"],"sourcesContent":[".spinner {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n color: var(--panneau-color-text-muted);\n}\n\n.circle {\n display: inline-block;\n flex: 0 0 auto;\n width: 1.25em;\n height: 1.25em;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: var(--panneau-radius-full);\n animation: spin 0.7s linear infinite;\n}\n\n.sm .circle {\n width: 1em;\n height: 1em;\n}\n\n.lg .circle {\n width: 2em;\n height: 2em;\n border-width: 3px;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .circle {\n animation-duration: 2s;\n }\n}\n"],"mappings":""}
|