@rojaostudio/ds 1.0.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/LICENSE +21 -0
- package/README.md +89 -0
- package/brand/rojao-black-on-white.png +0 -0
- package/brand/rojao-black.png +0 -0
- package/brand/rojao-white-on-black.png +0 -0
- package/brand/rojao-white.png +0 -0
- package/dist/chunk-ORMEWXMH.js +37 -0
- package/dist/compat/generate.d.ts +6 -0
- package/dist/compat/generate.js +1 -0
- package/dist/compat/recipes.d.ts +1 -0
- package/dist/compat/recipes.js +1 -0
- package/dist/compat/themes.d.ts +1 -0
- package/dist/compat/themes.js +1 -0
- package/dist/compat/tokens.d.ts +1 -0
- package/dist/compat/tokens.js +1 -0
- package/dist/components/accordion.d.ts +35 -0
- package/dist/components/accordion.js +95 -0
- package/dist/components/alert.d.ts +24 -0
- package/dist/components/alert.js +72 -0
- package/dist/components/avatar.d.ts +45 -0
- package/dist/components/avatar.js +97 -0
- package/dist/components/badge.d.ts +45 -0
- package/dist/components/badge.js +114 -0
- package/dist/components/blocker-card.d.ts +42 -0
- package/dist/components/blocker-card.js +45 -0
- package/dist/components/bottom-sheet.d.ts +31 -0
- package/dist/components/bottom-sheet.js +120 -0
- package/dist/components/breadcrumb.d.ts +28 -0
- package/dist/components/breadcrumb.js +52 -0
- package/dist/components/button.d.ts +27 -0
- package/dist/components/button.js +124 -0
- package/dist/components/card.d.ts +27 -0
- package/dist/components/card.js +52 -0
- package/dist/components/chat-bubble.d.ts +16 -0
- package/dist/components/chat-bubble.js +55 -0
- package/dist/components/checkbox.d.ts +14 -0
- package/dist/components/checkbox.js +78 -0
- package/dist/components/chip-input.d.ts +26 -0
- package/dist/components/chip-input.js +182 -0
- package/dist/components/chips.d.ts +22 -0
- package/dist/components/chips.js +94 -0
- package/dist/components/choice-card.d.ts +16 -0
- package/dist/components/choice-card.js +60 -0
- package/dist/components/choice-carousel.d.ts +16 -0
- package/dist/components/choice-carousel.js +154 -0
- package/dist/components/choice-preview-card.d.ts +37 -0
- package/dist/components/choice-preview-card.js +39 -0
- package/dist/components/color-input.d.ts +20 -0
- package/dist/components/color-input.js +79 -0
- package/dist/components/combobox.d.ts +70 -0
- package/dist/components/combobox.js +213 -0
- package/dist/components/context-menu.d.ts +33 -0
- package/dist/components/context-menu.js +70 -0
- package/dist/components/copilot-hint.d.ts +18 -0
- package/dist/components/copilot-hint.js +63 -0
- package/dist/components/copy-field.d.ts +16 -0
- package/dist/components/copy-field.js +41 -0
- package/dist/components/currency-input.d.ts +32 -0
- package/dist/components/currency-input.js +138 -0
- package/dist/components/danger-zone.d.ts +20 -0
- package/dist/components/danger-zone.js +21 -0
- package/dist/components/data-table-header.d.ts +43 -0
- package/dist/components/data-table-header.js +205 -0
- package/dist/components/date-picker.d.ts +40 -0
- package/dist/components/date-picker.js +252 -0
- package/dist/components/divider.d.ts +20 -0
- package/dist/components/divider.js +47 -0
- package/dist/components/drawer.d.ts +26 -0
- package/dist/components/drawer.js +82 -0
- package/dist/components/dropzone.d.ts +19 -0
- package/dist/components/dropzone.js +65 -0
- package/dist/components/empty-state.d.ts +48 -0
- package/dist/components/empty-state.js +91 -0
- package/dist/components/fab.d.ts +38 -0
- package/dist/components/fab.js +100 -0
- package/dist/components/filter-chip.d.ts +54 -0
- package/dist/components/filter-chip.js +66 -0
- package/dist/components/floating-stepper.d.ts +44 -0
- package/dist/components/floating-stepper.js +53 -0
- package/dist/components/form-card-header.d.ts +13 -0
- package/dist/components/form-card-header.js +8 -0
- package/dist/components/icon-button.d.ts +17 -0
- package/dist/components/icon-button.js +80 -0
- package/dist/components/image-crop-modal.d.ts +59 -0
- package/dist/components/image-crop-modal.js +240 -0
- package/dist/components/image-upload.d.ts +72 -0
- package/dist/components/image-upload.js +271 -0
- package/dist/components/index.d.ts +85 -0
- package/dist/components/index.js +200 -0
- package/dist/components/input.d.ts +25 -0
- package/dist/components/input.js +136 -0
- package/dist/components/insight-card.d.ts +19 -0
- package/dist/components/insight-card.js +27 -0
- package/dist/components/label.d.ts +16 -0
- package/dist/components/label.js +43 -0
- package/dist/components/media-tile.d.ts +24 -0
- package/dist/components/media-tile.js +28 -0
- package/dist/components/menu.d.ts +50 -0
- package/dist/components/menu.js +80 -0
- package/dist/components/modal.d.ts +25 -0
- package/dist/components/modal.js +71 -0
- package/dist/components/notice.d.ts +50 -0
- package/dist/components/notice.js +103 -0
- package/dist/components/option-tile.d.ts +60 -0
- package/dist/components/option-tile.js +144 -0
- package/dist/components/page-shell.d.ts +29 -0
- package/dist/components/page-shell.js +36 -0
- package/dist/components/page-skeleton.d.ts +35 -0
- package/dist/components/page-skeleton.js +12 -0
- package/dist/components/page-tabs.d.ts +35 -0
- package/dist/components/page-tabs.js +55 -0
- package/dist/components/pagination.d.ts +31 -0
- package/dist/components/pagination.js +80 -0
- package/dist/components/paywall-banner.d.ts +37 -0
- package/dist/components/paywall-banner.js +42 -0
- package/dist/components/paywall.d.ts +44 -0
- package/dist/components/paywall.js +55 -0
- package/dist/components/phone-frame.d.ts +9 -0
- package/dist/components/phone-frame.js +18 -0
- package/dist/components/phone-input.d.ts +24 -0
- package/dist/components/phone-input.js +92 -0
- package/dist/components/pix-icon.d.ts +8 -0
- package/dist/components/pix-icon.js +24 -0
- package/dist/components/popover.d.ts +44 -0
- package/dist/components/popover.js +140 -0
- package/dist/components/pricing-card.d.ts +42 -0
- package/dist/components/pricing-card.js +29 -0
- package/dist/components/qr-display.d.ts +19 -0
- package/dist/components/qr-display.js +24 -0
- package/dist/components/radio.d.ts +33 -0
- package/dist/components/radio.js +97 -0
- package/dist/components/row-actions.d.ts +24 -0
- package/dist/components/row-actions.js +76 -0
- package/dist/components/saving-bar-context.d.ts +40 -0
- package/dist/components/saving-bar-context.js +125 -0
- package/dist/components/saving-bar.d.ts +18 -0
- package/dist/components/saving-bar.js +72 -0
- package/dist/components/search.d.ts +30 -0
- package/dist/components/search.js +81 -0
- package/dist/components/section-card.d.ts +14 -0
- package/dist/components/section-card.js +49 -0
- package/dist/components/section-header.d.ts +29 -0
- package/dist/components/section-header.js +7 -0
- package/dist/components/select.d.ts +21 -0
- package/dist/components/select.js +140 -0
- package/dist/components/selectable-card.d.ts +35 -0
- package/dist/components/selectable-card.js +27 -0
- package/dist/components/setting-row.d.ts +33 -0
- package/dist/components/setting-row.js +19 -0
- package/dist/components/settings-list.d.ts +25 -0
- package/dist/components/settings-list.js +22 -0
- package/dist/components/skeleton.d.ts +24 -0
- package/dist/components/skeleton.js +49 -0
- package/dist/components/slider.d.ts +32 -0
- package/dist/components/slider.js +79 -0
- package/dist/components/spinner.d.ts +14 -0
- package/dist/components/spinner.js +36 -0
- package/dist/components/step-progress.d.ts +12 -0
- package/dist/components/step-progress.js +24 -0
- package/dist/components/summary-bar.d.ts +31 -0
- package/dist/components/summary-bar.js +54 -0
- package/dist/components/table.d.ts +23 -0
- package/dist/components/table.js +80 -0
- package/dist/components/textarea.d.ts +21 -0
- package/dist/components/textarea.js +95 -0
- package/dist/components/themed.d.ts +36 -0
- package/dist/components/themed.js +22 -0
- package/dist/components/time-picker.d.ts +34 -0
- package/dist/components/time-picker.js +213 -0
- package/dist/components/toaster.d.ts +84 -0
- package/dist/components/toaster.js +284 -0
- package/dist/components/toggle-card-compact.d.ts +21 -0
- package/dist/components/toggle-card-compact.js +99 -0
- package/dist/components/toggle-card.d.ts +15 -0
- package/dist/components/toggle-card.js +76 -0
- package/dist/components/toggle-group.d.ts +67 -0
- package/dist/components/toggle-group.js +80 -0
- package/dist/components/toggle.d.ts +13 -0
- package/dist/components/toggle.js +64 -0
- package/dist/components/tooltip.d.ts +17 -0
- package/dist/components/tooltip.js +89 -0
- package/dist/components/typing-indicator.d.ts +8 -0
- package/dist/components/typing-indicator.js +27 -0
- package/dist/components/use-dismiss.d.ts +9 -0
- package/dist/components/use-dismiss.js +28 -0
- package/dist/components/use-focus-trap.d.ts +5 -0
- package/dist/components/use-focus-trap.js +54 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +89 -0
- package/dist/targets/native/components/accordion.d.ts +18 -0
- package/dist/targets/native/components/accordion.js +122 -0
- package/dist/targets/native/components/alert.d.ts +16 -0
- package/dist/targets/native/components/alert.js +58 -0
- package/dist/targets/native/components/avatar.d.ts +25 -0
- package/dist/targets/native/components/avatar.js +88 -0
- package/dist/targets/native/components/badge.d.ts +27 -0
- package/dist/targets/native/components/badge.js +59 -0
- package/dist/targets/native/components/button.d.ts +18 -0
- package/dist/targets/native/components/button.js +84 -0
- package/dist/targets/native/components/card.d.ts +6 -0
- package/dist/targets/native/components/card.js +36 -0
- package/dist/targets/native/components/checkbox.d.ts +12 -0
- package/dist/targets/native/components/checkbox.js +59 -0
- package/dist/targets/native/components/chips.d.ts +17 -0
- package/dist/targets/native/components/chips.js +77 -0
- package/dist/targets/native/components/choice-card.d.ts +11 -0
- package/dist/targets/native/components/choice-card.js +52 -0
- package/dist/targets/native/components/context-menu.d.ts +11 -0
- package/dist/targets/native/components/context-menu.js +19 -0
- package/dist/targets/native/components/currency-input.d.ts +22 -0
- package/dist/targets/native/components/currency-input.js +105 -0
- package/dist/targets/native/components/danger-zone.d.ts +13 -0
- package/dist/targets/native/components/danger-zone.js +27 -0
- package/dist/targets/native/components/date-picker.d.ts +13 -0
- package/dist/targets/native/components/date-picker.js +185 -0
- package/dist/targets/native/components/divider.d.ts +9 -0
- package/dist/targets/native/components/divider.js +36 -0
- package/dist/targets/native/components/empty-state.d.ts +13 -0
- package/dist/targets/native/components/empty-state.js +10 -0
- package/dist/targets/native/components/fab.d.ts +25 -0
- package/dist/targets/native/components/fab.js +112 -0
- package/dist/targets/native/components/filter-chip.d.ts +22 -0
- package/dist/targets/native/components/filter-chip.js +70 -0
- package/dist/targets/native/components/form-field.d.ts +13 -0
- package/dist/targets/native/components/form-field.js +29 -0
- package/dist/targets/native/components/form-screen.d.ts +19 -0
- package/dist/targets/native/components/form-screen.js +88 -0
- package/dist/targets/native/components/google-icon.d.ts +8 -0
- package/dist/targets/native/components/google-icon.js +32 -0
- package/dist/targets/native/components/icon-button.d.ts +18 -0
- package/dist/targets/native/components/icon-button.js +80 -0
- package/dist/targets/native/components/icon.d.ts +11 -0
- package/dist/targets/native/components/icon.js +9 -0
- package/dist/targets/native/components/image-upload.d.ts +12 -0
- package/dist/targets/native/components/image-upload.js +95 -0
- package/dist/targets/native/components/index.d.ts +45 -0
- package/dist/targets/native/components/index.js +100 -0
- package/dist/targets/native/components/input.d.ts +17 -0
- package/dist/targets/native/components/input.js +103 -0
- package/dist/targets/native/components/list-item.d.ts +20 -0
- package/dist/targets/native/components/list-item.js +71 -0
- package/dist/targets/native/components/menu.d.ts +24 -0
- package/dist/targets/native/components/menu.js +71 -0
- package/dist/targets/native/components/modal.d.ts +15 -0
- package/dist/targets/native/components/modal.js +110 -0
- package/dist/targets/native/components/paywall-banner.d.ts +11 -0
- package/dist/targets/native/components/paywall-banner.js +46 -0
- package/dist/targets/native/components/paywall.d.ts +18 -0
- package/dist/targets/native/components/paywall.js +61 -0
- package/dist/targets/native/components/radio.d.ts +20 -0
- package/dist/targets/native/components/radio.js +71 -0
- package/dist/targets/native/components/search.d.ts +22 -0
- package/dist/targets/native/components/search.js +92 -0
- package/dist/targets/native/components/select.d.ts +17 -0
- package/dist/targets/native/components/select.js +86 -0
- package/dist/targets/native/components/sheet.d.ts +11 -0
- package/dist/targets/native/components/sheet.js +51 -0
- package/dist/targets/native/components/skeleton.d.ts +18 -0
- package/dist/targets/native/components/skeleton.js +52 -0
- package/dist/targets/native/components/slider.d.ts +18 -0
- package/dist/targets/native/components/slider.js +153 -0
- package/dist/targets/native/components/spinner.d.ts +7 -0
- package/dist/targets/native/components/spinner.js +10 -0
- package/dist/targets/native/components/stepper.d.ts +10 -0
- package/dist/targets/native/components/stepper.js +33 -0
- package/dist/targets/native/components/switch.d.ts +20 -0
- package/dist/targets/native/components/switch.js +68 -0
- package/dist/targets/native/components/text.d.ts +12 -0
- package/dist/targets/native/components/text.js +31 -0
- package/dist/targets/native/components/textarea.d.ts +13 -0
- package/dist/targets/native/components/textarea.js +92 -0
- package/dist/targets/native/components/theme.d.ts +18 -0
- package/dist/targets/native/components/theme.js +20 -0
- package/dist/targets/native/components/toaster.d.ts +35 -0
- package/dist/targets/native/components/toaster.js +159 -0
- package/dist/targets/native/fonts.d.ts +9 -0
- package/dist/targets/native/fonts.js +10 -0
- package/dist/targets/native/icons.d.ts +1 -0
- package/dist/targets/native/icons.js +1 -0
- package/dist/targets/native/index.d.ts +3 -0
- package/dist/targets/native/index.js +11 -0
- package/dist/targets/native/preset.cjs +69 -0
- package/dist/targets/native/resolve.d.ts +22 -0
- package/dist/targets/native/resolve.js +85 -0
- package/dist/targets/native/theme.css +118 -0
- package/dist/targets/native/theme.d.ts +117 -0
- package/dist/targets/native/theme.js +118 -0
- package/package.json +194 -0
- package/styles/_primitives.generated.css +284 -0
- package/styles/base.css +950 -0
- package/styles/themes/rojao.css +107 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SectionHeader — cabeçalho de seção fora de card: eyebrow (overline) opcional
|
|
6
|
+
* + título + texto de apoio. Areja a página agrupando conteúdo sem moldura.
|
|
7
|
+
*
|
|
8
|
+
* Uso:
|
|
9
|
+
* <SectionHeader title="Seções da vitrine" />
|
|
10
|
+
* <SectionHeader eyebrow="Conteúdo da vitrine" number="02" title="Seções da vitrine" description="Ative, desative e edite o que aparece" />
|
|
11
|
+
* <SectionHeader title="Zonas" action={<Button size="sm">Adicionar</Button>} />
|
|
12
|
+
*
|
|
13
|
+
* O eyebrow consome os tokens --font-size/weight/letter-spacing-eyebrow — a
|
|
14
|
+
* decisão de "quão pequeno/espaçado" vive em base.css, não em cada tela.
|
|
15
|
+
*/
|
|
16
|
+
interface SectionHeaderProps {
|
|
17
|
+
/** Micro-rótulo uppercase acima do título (overline/kicker). */
|
|
18
|
+
eyebrow?: string;
|
|
19
|
+
/** Número de seção/etapa — prefixa o eyebrow: "02 · CONTEÚDO". */
|
|
20
|
+
number?: string;
|
|
21
|
+
title: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Slot à direita do título (ação, badge). */
|
|
24
|
+
action?: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
declare function SectionHeader({ eyebrow, number, title, description, action, className }: SectionHeaderProps): react.JSX.Element;
|
|
28
|
+
|
|
29
|
+
export { SectionHeader, type SectionHeaderProps };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import "../chunk-ORMEWXMH.js";
|
|
2
|
+
function SectionHeader({ eyebrow, number, title, description, action, className = "" }) {
|
|
3
|
+
return /* @__PURE__ */ React.createElement("div", { className: ["mb-6", className].filter(Boolean).join(" ") }, eyebrow && /* @__PURE__ */ React.createElement("p", { className: "uppercase text-fg-muted mb-1.5 [font-size:var(--font-size-eyebrow)] [font-weight:var(--font-weight-eyebrow)] [letter-spacing:var(--letter-spacing-eyebrow)]" }, number ? `${number} \xB7 ${eyebrow}` : eyebrow), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("h2", { className: "text-body font-semibold text-fg-primary" }, title), description && /* @__PURE__ */ React.createElement("p", { className: "text-label text-fg-muted mt-1" }, description)), action && /* @__PURE__ */ React.createElement("div", { className: "shrink-0" }, action)));
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
SectionHeader
|
|
7
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { SelectHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
type SelectSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> {
|
|
6
|
+
label?: string;
|
|
7
|
+
helper?: string;
|
|
8
|
+
error?: string;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
options?: {
|
|
11
|
+
value: string;
|
|
12
|
+
label: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
}[];
|
|
15
|
+
size?: SelectSize;
|
|
16
|
+
required?: boolean;
|
|
17
|
+
optional?: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLSelectElement>>;
|
|
20
|
+
|
|
21
|
+
export { Select, type SelectProps, type SelectSize };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
__objRest,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "../chunk-ORMEWXMH.js";
|
|
6
|
+
import {
|
|
7
|
+
Children,
|
|
8
|
+
forwardRef,
|
|
9
|
+
isValidElement,
|
|
10
|
+
useEffect,
|
|
11
|
+
useId,
|
|
12
|
+
useRef,
|
|
13
|
+
useState
|
|
14
|
+
} from "react";
|
|
15
|
+
import { ChevronDown, Check } from "lucide-react";
|
|
16
|
+
import { BottomSheet } from "./bottom-sheet.js";
|
|
17
|
+
const SIZE = {
|
|
18
|
+
sm: { h: "h-control-sm", text: "text-caption", padL: "pl-2.5", padR: "pr-7" },
|
|
19
|
+
md: { h: "h-control-md", text: "text-label", padL: "pl-3", padR: "pr-9" },
|
|
20
|
+
lg: { h: "h-control-lg", text: "text-body", padL: "pl-4", padR: "pr-10" }
|
|
21
|
+
};
|
|
22
|
+
function optionsFromChildren(children) {
|
|
23
|
+
const out = [];
|
|
24
|
+
Children.forEach(children, (child) => {
|
|
25
|
+
var _a;
|
|
26
|
+
if (!isValidElement(child)) return;
|
|
27
|
+
const props = child.props;
|
|
28
|
+
if (child.type === "option" && props.value !== void 0) {
|
|
29
|
+
out.push({
|
|
30
|
+
value: String(props.value),
|
|
31
|
+
label: typeof props.children === "string" ? props.children : String((_a = props.children) != null ? _a : props.value),
|
|
32
|
+
disabled: props.disabled
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
const Select = forwardRef(function Select2(_a, ref) {
|
|
39
|
+
var _b = _a, { label, helper, error, options = [], placeholder, size = "md", required, optional, className = "", id, children } = _b, props = __objRest(_b, ["label", "helper", "error", "options", "placeholder", "size", "required", "optional", "className", "id", "children"]);
|
|
40
|
+
var _a2;
|
|
41
|
+
const generatedId = useId();
|
|
42
|
+
const selectId = id != null ? id : generatedId;
|
|
43
|
+
const sz = SIZE[size];
|
|
44
|
+
const innerRef = useRef(null);
|
|
45
|
+
const setRefs = (el) => {
|
|
46
|
+
innerRef.current = el;
|
|
47
|
+
if (typeof ref === "function") ref(el);
|
|
48
|
+
else if (ref) ref.current = el;
|
|
49
|
+
};
|
|
50
|
+
const [isXs, setIsXs] = useState(false);
|
|
51
|
+
const [sheetOpen, setSheetOpen] = useState(false);
|
|
52
|
+
const [sheetValue, setSheetValue] = useState("");
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const mq = window.matchMedia("(max-width: 639px)");
|
|
55
|
+
const update = () => setIsXs(mq.matches);
|
|
56
|
+
update();
|
|
57
|
+
mq.addEventListener("change", update);
|
|
58
|
+
return () => mq.removeEventListener("change", update);
|
|
59
|
+
}, []);
|
|
60
|
+
const allOptions = options.length > 0 ? options : optionsFromChildren(children);
|
|
61
|
+
function openSheet() {
|
|
62
|
+
var _a3, _b2;
|
|
63
|
+
setSheetValue((_b2 = (_a3 = innerRef.current) == null ? void 0 : _a3.value) != null ? _b2 : "");
|
|
64
|
+
setSheetOpen(true);
|
|
65
|
+
}
|
|
66
|
+
function commitSheetValue(value) {
|
|
67
|
+
var _a3;
|
|
68
|
+
const el = innerRef.current;
|
|
69
|
+
setSheetOpen(false);
|
|
70
|
+
if (!el || el.value === value) return;
|
|
71
|
+
const setter = (_a3 = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, "value")) == null ? void 0 : _a3.set;
|
|
72
|
+
setter == null ? void 0 : setter.call(el, value);
|
|
73
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
74
|
+
}
|
|
75
|
+
return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1.5 w-full" }, label && /* @__PURE__ */ React.createElement("label", { htmlFor: selectId, className: "inline-flex items-center gap-1 text-label font-medium text-fg-primary" }, /* @__PURE__ */ React.createElement("span", null, label), required && /* @__PURE__ */ React.createElement("span", { className: "text-danger", "aria-label": "obrigat\xF3rio" }, "*"), optional && !required && /* @__PURE__ */ React.createElement("span", { className: "text-fg-muted font-normal" }, "(opcional)")), /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(
|
|
76
|
+
"select",
|
|
77
|
+
__spreadValues({
|
|
78
|
+
ref: setRefs,
|
|
79
|
+
id: selectId,
|
|
80
|
+
required,
|
|
81
|
+
className: [
|
|
82
|
+
"w-full rounded-(--radius-control) appearance-none",
|
|
83
|
+
"bg-surface-default text-fg-primary",
|
|
84
|
+
"border transition-colors outline-none",
|
|
85
|
+
sz.h,
|
|
86
|
+
sz.text,
|
|
87
|
+
sz.padL,
|
|
88
|
+
sz.padR,
|
|
89
|
+
error ? "border-danger focus:border-danger focus:ring-2 focus:ring-danger/20" : "border-stroke-control focus:border-stroke-focus focus:ring-2 focus:ring-stroke-focus/20",
|
|
90
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
91
|
+
className
|
|
92
|
+
].filter(Boolean).join(" "),
|
|
93
|
+
"aria-invalid": error ? true : void 0,
|
|
94
|
+
"aria-describedby": error ? `${selectId}-error` : helper ? `${selectId}-helper` : void 0
|
|
95
|
+
}, props),
|
|
96
|
+
placeholder && /* @__PURE__ */ React.createElement("option", { value: "", disabled: true, hidden: true }, placeholder),
|
|
97
|
+
options.map((o) => /* @__PURE__ */ React.createElement("option", { key: o.value, value: o.value, disabled: o.disabled }, o.label)),
|
|
98
|
+
children
|
|
99
|
+
), /* @__PURE__ */ React.createElement(
|
|
100
|
+
ChevronDown,
|
|
101
|
+
{
|
|
102
|
+
size: size === "sm" ? 14 : size === "lg" ? 18 : 16,
|
|
103
|
+
className: [
|
|
104
|
+
"absolute top-1/2 -translate-y-1/2 text-fg-muted pointer-events-none",
|
|
105
|
+
size === "sm" ? "right-2.5" : size === "lg" ? "right-3.5" : "right-3"
|
|
106
|
+
].join(" ")
|
|
107
|
+
}
|
|
108
|
+
), isXs && !props.disabled && allOptions.length > 0 && /* @__PURE__ */ React.createElement(
|
|
109
|
+
"button",
|
|
110
|
+
{
|
|
111
|
+
type: "button",
|
|
112
|
+
"aria-label": (_a2 = label != null ? label : placeholder) != null ? _a2 : "Selecionar",
|
|
113
|
+
"aria-haspopup": "dialog",
|
|
114
|
+
onClick: openSheet,
|
|
115
|
+
className: "absolute inset-0 w-full h-full rounded-(--radius-control) opacity-0"
|
|
116
|
+
}
|
|
117
|
+
)), error && /* @__PURE__ */ React.createElement("p", { id: `${selectId}-error`, className: "text-caption text-danger-text" }, error), !error && helper && /* @__PURE__ */ React.createElement("p", { id: `${selectId}-helper`, className: "text-caption text-fg-muted" }, helper), isXs && /* @__PURE__ */ React.createElement(BottomSheet, { open: sheetOpen, onClose: () => setSheetOpen(false), title: label != null ? label : placeholder }, /* @__PURE__ */ React.createElement("div", { className: "pb-2" }, allOptions.map((o) => {
|
|
118
|
+
const selected = o.value === sheetValue;
|
|
119
|
+
return /* @__PURE__ */ React.createElement(
|
|
120
|
+
"button",
|
|
121
|
+
{
|
|
122
|
+
key: o.value,
|
|
123
|
+
type: "button",
|
|
124
|
+
disabled: o.disabled,
|
|
125
|
+
onClick: () => commitSheetValue(o.value),
|
|
126
|
+
className: [
|
|
127
|
+
"w-full flex items-center justify-between gap-3 px-1 py-3.5 text-left text-label",
|
|
128
|
+
"border-b border-stroke-subtle last:border-0 transition-colors",
|
|
129
|
+
selected ? "font-medium text-fg-primary" : "text-fg-secondary",
|
|
130
|
+
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
131
|
+
].join(" ")
|
|
132
|
+
},
|
|
133
|
+
/* @__PURE__ */ React.createElement("span", { className: "min-w-0 flex-1" }, o.label),
|
|
134
|
+
selected && /* @__PURE__ */ React.createElement(Check, { size: 16, className: "shrink-0" })
|
|
135
|
+
);
|
|
136
|
+
}))));
|
|
137
|
+
});
|
|
138
|
+
export {
|
|
139
|
+
Select
|
|
140
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SelectableCard — cartão CLICÁVEL genérico (tile de ação OU escolha).
|
|
6
|
+
*
|
|
7
|
+
* Resolve os "card-as-div" reimplementados como `<button className="rounded-xl border">`:
|
|
8
|
+
* tiles de ação (abrir modal, navegar), cards de escolha, pricing card (com ribbon).
|
|
9
|
+
* Renderiza `<button>` (ação) ou `<a>` (navegação) — semântica correta, foco acessível.
|
|
10
|
+
*
|
|
11
|
+
* Estado `selected` usa destaque NEUTRO (border-focus + surface-raised) — NÃO usa brand,
|
|
12
|
+
* então é seguro no admin (onde cor de marca é proibida) e na vitrine.
|
|
13
|
+
*
|
|
14
|
+
* indicator:
|
|
15
|
+
* 'radio' — bolinha de seleção (escolha exclusiva)
|
|
16
|
+
* 'check' — check quando selecionado (multi-seleção/confirmação)
|
|
17
|
+
* 'chevron' — seta de navegação (tile que leva a outra tela)
|
|
18
|
+
* 'none' — sem indicador (tile de ação puro)
|
|
19
|
+
*/
|
|
20
|
+
interface SelectableCardProps {
|
|
21
|
+
selected?: boolean;
|
|
22
|
+
onClick?: () => void;
|
|
23
|
+
/** Elemento renderizado: 'button' (ação, default) ou 'a' (navegação). */
|
|
24
|
+
as?: 'button' | 'a';
|
|
25
|
+
href?: string;
|
|
26
|
+
indicator?: 'radio' | 'check' | 'chevron' | 'none';
|
|
27
|
+
/** Selo flutuante no topo (ex: "Mais popular" no pricing card). */
|
|
28
|
+
ribbon?: ReactNode;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
className?: string;
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
declare function SelectableCard({ selected, onClick, as, href, indicator, ribbon, disabled, className, children, }: SelectableCardProps): react.JSX.Element;
|
|
34
|
+
|
|
35
|
+
export { SelectableCard, type SelectableCardProps };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import "../chunk-ORMEWXMH.js";
|
|
3
|
+
import { Check, ChevronRight } from "lucide-react";
|
|
4
|
+
function SelectableCard({
|
|
5
|
+
selected = false,
|
|
6
|
+
onClick,
|
|
7
|
+
as = "button",
|
|
8
|
+
href,
|
|
9
|
+
indicator = "none",
|
|
10
|
+
ribbon,
|
|
11
|
+
disabled = false,
|
|
12
|
+
className = "",
|
|
13
|
+
children
|
|
14
|
+
}) {
|
|
15
|
+
const base = "relative w-full flex items-center gap-4 px-4 py-4 rounded-(--radius-card) border text-left transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stroke-focus";
|
|
16
|
+
const state = selected ? "border-2 border-stroke-focus bg-surface-raised" : "border border-stroke-default bg-surface-default hover:border-stroke-strong";
|
|
17
|
+
const disabledCls = disabled ? "opacity-50 cursor-not-allowed pointer-events-none" : "cursor-pointer";
|
|
18
|
+
const cls = [base, state, disabledCls, className].filter(Boolean).join(" ");
|
|
19
|
+
const inner = /* @__PURE__ */ React.createElement(React.Fragment, null, ribbon && /* @__PURE__ */ React.createElement("span", { className: "absolute -top-3 left-1/2 -translate-x-1/2" }, ribbon), /* @__PURE__ */ React.createElement("div", { className: "flex-1 min-w-0" }, children), indicator === "radio" && /* @__PURE__ */ React.createElement("span", { className: `shrink-0 size-4 rounded-full border-2 flex items-center justify-center ${selected ? "border-stroke-focus" : "border-stroke-strong"}` }, selected && /* @__PURE__ */ React.createElement("span", { className: "size-2 rounded-full bg-stroke-focus" })), indicator === "check" && selected && /* @__PURE__ */ React.createElement(Check, { className: "shrink-0 size-4 text-fg-primary", strokeWidth: 2.5 }), indicator === "chevron" && /* @__PURE__ */ React.createElement(ChevronRight, { className: "shrink-0 size-4 text-fg-muted", strokeWidth: 2 }));
|
|
20
|
+
if (as === "a") {
|
|
21
|
+
return /* @__PURE__ */ React.createElement("a", { href, className: cls, "aria-disabled": disabled || void 0, "aria-current": selected || void 0 }, inner);
|
|
22
|
+
}
|
|
23
|
+
return /* @__PURE__ */ React.createElement("button", { type: "button", onClick, disabled, "aria-pressed": selected, className: cls }, inner);
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
SelectableCard
|
|
27
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SettingRow — uma linha de configuração: título + texto de apoio à ESQUERDA,
|
|
6
|
+
* controle à DIREITA. Padrão "Settings" (rows com divisor, no lugar de card-por-item).
|
|
7
|
+
* Empilha no mobile (label em cima, controle embaixo). Os divisores entre rows são
|
|
8
|
+
* aplicados pelo <SettingsList> que as agrupa — a row nunca desenha a própria borda.
|
|
9
|
+
*
|
|
10
|
+
* controlWidth:
|
|
11
|
+
* 'auto' — controle estreito encostado à direita (toggle, pill, dropdown curto). DEFAULT.
|
|
12
|
+
* 'fill' — input/select que ocupa uma coluna de largura previsível (até ~20rem).
|
|
13
|
+
* 'full' — controle LARGO (fileira de <ChoicePreviewCard>): largura total, sempre abaixo do label.
|
|
14
|
+
*
|
|
15
|
+
* a11y: passe `htmlFor` quando o controle for um input/toggle único — o label vira
|
|
16
|
+
* <label> associado (sem isso, leitores de tela não associam rótulo↔controle).
|
|
17
|
+
*/
|
|
18
|
+
interface SettingRowProps {
|
|
19
|
+
label: ReactNode;
|
|
20
|
+
description?: ReactNode;
|
|
21
|
+
/** Ícone opcional à esquerda do label. */
|
|
22
|
+
icon?: ReactNode;
|
|
23
|
+
/** id do controle — associa o label (htmlFor) pra leitores de tela. */
|
|
24
|
+
htmlFor?: string;
|
|
25
|
+
controlWidth?: 'auto' | 'fill' | 'full';
|
|
26
|
+
/** Alinhamento vertical do controle vs. label. 'start' p/ textarea/multilinha. */
|
|
27
|
+
align?: 'center' | 'start';
|
|
28
|
+
control: ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
declare function SettingRow({ label, description, icon, htmlFor, controlWidth, align, control, className, }: SettingRowProps): react.JSX.Element;
|
|
32
|
+
|
|
33
|
+
export { SettingRow, type SettingRowProps };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import "../chunk-ORMEWXMH.js";
|
|
2
|
+
function SettingRow({
|
|
3
|
+
label,
|
|
4
|
+
description,
|
|
5
|
+
icon,
|
|
6
|
+
htmlFor,
|
|
7
|
+
controlWidth = "auto",
|
|
8
|
+
align = "center",
|
|
9
|
+
control,
|
|
10
|
+
className = ""
|
|
11
|
+
}) {
|
|
12
|
+
const cols = controlWidth === "full" ? "" : controlWidth === "fill" ? "sm:grid-cols-[minmax(0,1fr)_minmax(0,20rem)]" : "sm:grid-cols-[1fr_auto]";
|
|
13
|
+
const alignCls = align === "start" ? "sm:items-start" : "sm:items-center";
|
|
14
|
+
const LabelTag = htmlFor ? "label" : "div";
|
|
15
|
+
return /* @__PURE__ */ React.createElement("div", { className: ["grid grid-cols-1 gap-x-6 gap-y-3 py-4", cols, alignCls, className].filter(Boolean).join(" ") }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3 min-w-0" }, icon && /* @__PURE__ */ React.createElement("div", { className: "shrink-0 text-fg-muted mt-0.5" }, icon), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement(LabelTag, { htmlFor, className: "block text-sm font-medium text-fg-primary" }, label), description && /* @__PURE__ */ React.createElement("div", { className: "text-sm text-fg-muted mt-0.5 leading-snug" }, description))), /* @__PURE__ */ React.createElement("div", { className: controlWidth === "auto" ? "sm:justify-self-end" : "" }, control));
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
SettingRow
|
|
19
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SettingsList — agrupa <SettingRow> num bloco com divisores entre elas. Substitui o
|
|
6
|
+
* boilerplate repetido `Card > CardBody noPadding > div.divide-y` espalhado pelas telas.
|
|
7
|
+
*
|
|
8
|
+
* O título do grupo é simples (sem número/eyebrow) — o padrão "Settings" não numera
|
|
9
|
+
* seções (são ajustes paralelos, não etapas). Divisor = `stroke-default` (visível, não o
|
|
10
|
+
* `stroke-subtle` quase invisível do Untitled UI) — acessibilidade > estética de Figma.
|
|
11
|
+
*/
|
|
12
|
+
interface SettingsListProps {
|
|
13
|
+
/** Título simples do grupo. Omita se o grupo não tem cabeçalho. */
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
/** Ação à direita do título (delega ao SectionHeader). */
|
|
17
|
+
action?: ReactNode;
|
|
18
|
+
/** Moldura (card) em volta. Default true; false = lista solta. */
|
|
19
|
+
framed?: boolean;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
className?: string;
|
|
22
|
+
}
|
|
23
|
+
declare function SettingsList({ title, description, action, framed, children, className, }: SettingsListProps): react.JSX.Element;
|
|
24
|
+
|
|
25
|
+
export { SettingsList, type SettingsListProps };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import "../chunk-ORMEWXMH.js";
|
|
2
|
+
import { SectionHeader } from "./section-header.js";
|
|
3
|
+
function SettingsList({
|
|
4
|
+
title,
|
|
5
|
+
description,
|
|
6
|
+
action,
|
|
7
|
+
framed = true,
|
|
8
|
+
children,
|
|
9
|
+
className = ""
|
|
10
|
+
}) {
|
|
11
|
+
const list = /* @__PURE__ */ React.createElement(
|
|
12
|
+
"div",
|
|
13
|
+
{
|
|
14
|
+
className: framed ? "rounded-(--radius-card) border border-stroke-default bg-surface-default px-4 [&>*]:border-t [&>*]:border-stroke-default [&>*:first-child]:border-t-0" : "[&>*]:border-t [&>*]:border-stroke-default [&>*:first-child]:border-t-0"
|
|
15
|
+
},
|
|
16
|
+
children
|
|
17
|
+
);
|
|
18
|
+
return /* @__PURE__ */ React.createElement("section", { className: ["space-y-3", className].filter(Boolean).join(" ") }, title && /* @__PURE__ */ React.createElement(SectionHeader, { title, description, action }), list);
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
SettingsList
|
|
22
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
declare const SKELETON_VARIANTS: {
|
|
4
|
+
readonly text: "h-4 w-full";
|
|
5
|
+
readonly title: "h-6 w-3/5";
|
|
6
|
+
readonly avatar: "size-10 rounded-full";
|
|
7
|
+
readonly circle: "size-12 rounded-full";
|
|
8
|
+
readonly button: "h-10 w-24 rounded-(--radius-card)";
|
|
9
|
+
readonly card: "h-32 w-full rounded-(--radius-card)";
|
|
10
|
+
readonly line: "h-3 w-full";
|
|
11
|
+
};
|
|
12
|
+
type SkeletonVariant = keyof typeof SKELETON_VARIANTS;
|
|
13
|
+
interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
14
|
+
variant?: SkeletonVariant;
|
|
15
|
+
/** Renderiza N skeletons stackados (útil pra simular lista). */
|
|
16
|
+
count?: number;
|
|
17
|
+
/** Gap entre skeletons quando count > 1. default = 'sm'. */
|
|
18
|
+
gap?: 'sm' | 'md' | 'lg';
|
|
19
|
+
/** Sem animação pulse (placeholder estático). */
|
|
20
|
+
noPulse?: boolean;
|
|
21
|
+
}
|
|
22
|
+
declare function Skeleton({ variant, count, gap, noPulse, className, ...props }: SkeletonProps): react.JSX.Element;
|
|
23
|
+
|
|
24
|
+
export { Skeleton, type SkeletonProps, type SkeletonVariant };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__objRest,
|
|
3
|
+
__spreadProps,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "../chunk-ORMEWXMH.js";
|
|
6
|
+
const SKELETON_VARIANTS = {
|
|
7
|
+
text: "h-4 w-full",
|
|
8
|
+
title: "h-6 w-3/5",
|
|
9
|
+
avatar: "size-10 rounded-full",
|
|
10
|
+
circle: "size-12 rounded-full",
|
|
11
|
+
button: "h-10 w-24 rounded-(--radius-card)",
|
|
12
|
+
card: "h-32 w-full rounded-(--radius-card)",
|
|
13
|
+
line: "h-3 w-full"
|
|
14
|
+
};
|
|
15
|
+
const GAP = { sm: "gap-2", md: "gap-3", lg: "gap-4" };
|
|
16
|
+
function Skeleton(_a) {
|
|
17
|
+
var _b = _a, {
|
|
18
|
+
variant = "text",
|
|
19
|
+
count = 1,
|
|
20
|
+
gap = "sm",
|
|
21
|
+
noPulse = false,
|
|
22
|
+
className = ""
|
|
23
|
+
} = _b, props = __objRest(_b, [
|
|
24
|
+
"variant",
|
|
25
|
+
"count",
|
|
26
|
+
"gap",
|
|
27
|
+
"noPulse",
|
|
28
|
+
"className"
|
|
29
|
+
]);
|
|
30
|
+
const classes = [
|
|
31
|
+
noPulse ? "" : "animate-pulse",
|
|
32
|
+
"rounded bg-stroke-default/50",
|
|
33
|
+
SKELETON_VARIANTS[variant],
|
|
34
|
+
className
|
|
35
|
+
].filter(Boolean).join(" ");
|
|
36
|
+
if (count === 1) return /* @__PURE__ */ React.createElement("div", __spreadValues({ className: classes }, props));
|
|
37
|
+
return /* @__PURE__ */ React.createElement("div", { className: ["flex flex-col", GAP[gap]].join(" ") }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React.createElement(
|
|
38
|
+
"div",
|
|
39
|
+
__spreadProps(__spreadValues({
|
|
40
|
+
key: i,
|
|
41
|
+
className: classes
|
|
42
|
+
}, i === 0 ? props : {}), {
|
|
43
|
+
style: variant === "text" && i === count - 1 ? { width: "70%" } : void 0
|
|
44
|
+
})
|
|
45
|
+
)));
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
Skeleton
|
|
49
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { InputHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Slider — input range single (sem range duplo). Inspirado em M3 Slider.
|
|
6
|
+
*
|
|
7
|
+
* Uso:
|
|
8
|
+
* <Slider value={vol} onChange={setVol} min={0} max={100} />
|
|
9
|
+
* <Slider value={qty} onChange={setQty} min={1} max={50} step={1} showValue />
|
|
10
|
+
* <Slider value={pct} onChange={setPct} formatValue={v => `${v}%`} showValue />
|
|
11
|
+
*
|
|
12
|
+
* Sem range duplo por enquanto (M3 e shadcn separam em RangeSlider). Adicionar
|
|
13
|
+
* componente próprio quando precisar.
|
|
14
|
+
*/
|
|
15
|
+
interface SliderProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange' | 'value' | 'size'> {
|
|
16
|
+
value: number;
|
|
17
|
+
onChange: (value: number) => void;
|
|
18
|
+
min?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
step?: number;
|
|
21
|
+
/** Mostra valor atual à direita. */
|
|
22
|
+
showValue?: boolean;
|
|
23
|
+
/** Formata valor (ex: `v => `R$ ${v}``). */
|
|
24
|
+
formatValue?: (value: number) => string;
|
|
25
|
+
/** Mostra ticks min/max abaixo. */
|
|
26
|
+
showRange?: boolean;
|
|
27
|
+
size?: 'sm' | 'md';
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
declare const Slider: react.ForwardRefExoticComponent<SliderProps & react.RefAttributes<HTMLInputElement>>;
|
|
31
|
+
|
|
32
|
+
export { Slider, type SliderProps };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
__objRest,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "../chunk-ORMEWXMH.js";
|
|
6
|
+
import { forwardRef, useId } from "react";
|
|
7
|
+
const TRACK_HEIGHT = { sm: 4, md: 6 };
|
|
8
|
+
const THUMB_SIZE = { sm: 14, md: 18 };
|
|
9
|
+
const Slider = forwardRef(function Slider2(_a, ref) {
|
|
10
|
+
var _b = _a, {
|
|
11
|
+
value,
|
|
12
|
+
onChange,
|
|
13
|
+
min = 0,
|
|
14
|
+
max = 100,
|
|
15
|
+
step = 1,
|
|
16
|
+
showValue = false,
|
|
17
|
+
formatValue,
|
|
18
|
+
showRange = false,
|
|
19
|
+
size = "md",
|
|
20
|
+
disabled,
|
|
21
|
+
className = ""
|
|
22
|
+
} = _b, rest = __objRest(_b, [
|
|
23
|
+
"value",
|
|
24
|
+
"onChange",
|
|
25
|
+
"min",
|
|
26
|
+
"max",
|
|
27
|
+
"step",
|
|
28
|
+
"showValue",
|
|
29
|
+
"formatValue",
|
|
30
|
+
"showRange",
|
|
31
|
+
"size",
|
|
32
|
+
"disabled",
|
|
33
|
+
"className"
|
|
34
|
+
]);
|
|
35
|
+
const id = useId();
|
|
36
|
+
const pct = (value - min) / (max - min) * 100;
|
|
37
|
+
const fmt = formatValue != null ? formatValue : ((v) => String(v));
|
|
38
|
+
return /* @__PURE__ */ React.createElement("div", { className: ["flex flex-col gap-2", className].join(" ") }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "relative flex-1 flex items-center", style: { height: THUMB_SIZE[size] } }, /* @__PURE__ */ React.createElement(
|
|
39
|
+
"input",
|
|
40
|
+
__spreadValues({
|
|
41
|
+
ref,
|
|
42
|
+
id,
|
|
43
|
+
type: "range",
|
|
44
|
+
min,
|
|
45
|
+
max,
|
|
46
|
+
step,
|
|
47
|
+
value,
|
|
48
|
+
disabled,
|
|
49
|
+
onChange: (e) => onChange(Number(e.target.value)),
|
|
50
|
+
className: [
|
|
51
|
+
"rojao-slider absolute inset-0 w-full bg-transparent appearance-none cursor-pointer",
|
|
52
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-stroke-focus focus-visible:ring-offset-2 focus-visible:rounded-full",
|
|
53
|
+
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
54
|
+
].join(" "),
|
|
55
|
+
style: {
|
|
56
|
+
["--rojao-slider-pct"]: `${pct}%`,
|
|
57
|
+
["--rojao-slider-track-h"]: `${TRACK_HEIGHT[size]}px`,
|
|
58
|
+
["--rojao-slider-thumb-size"]: `${THUMB_SIZE[size]}px`
|
|
59
|
+
}
|
|
60
|
+
}, rest)
|
|
61
|
+
), /* @__PURE__ */ React.createElement(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
"aria-hidden": true,
|
|
65
|
+
className: "absolute inset-x-0 rounded-full bg-stroke-default pointer-events-none",
|
|
66
|
+
style: { height: TRACK_HEIGHT[size] }
|
|
67
|
+
}
|
|
68
|
+
), /* @__PURE__ */ React.createElement(
|
|
69
|
+
"div",
|
|
70
|
+
{
|
|
71
|
+
"aria-hidden": true,
|
|
72
|
+
className: "absolute left-0 rounded-full bg-brand-primary pointer-events-none",
|
|
73
|
+
style: { height: TRACK_HEIGHT[size], width: `${pct}%` }
|
|
74
|
+
}
|
|
75
|
+
)), showValue && /* @__PURE__ */ React.createElement("span", { className: "text-label font-medium text-fg-primary tabular-nums shrink-0 min-w-[3ch] text-right" }, fmt(value))), showRange && /* @__PURE__ */ React.createElement("div", { className: "flex justify-between text-[11px] font-mono text-fg-muted" }, /* @__PURE__ */ React.createElement("span", null, fmt(min)), /* @__PURE__ */ React.createElement("span", null, fmt(max))));
|
|
76
|
+
});
|
|
77
|
+
export {
|
|
78
|
+
Slider
|
|
79
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
4
|
+
type SpinnerColor = 'current' | 'brand' | 'muted' | 'inverse';
|
|
5
|
+
interface SpinnerProps {
|
|
6
|
+
size?: SpinnerSize;
|
|
7
|
+
color?: SpinnerColor;
|
|
8
|
+
/** Texto pra leitor de tela. default = "Carregando…". */
|
|
9
|
+
label?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function Spinner({ size, color, label, className, }: SpinnerProps): react.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import "../chunk-ORMEWXMH.js";
|
|
2
|
+
const SIZE = {
|
|
3
|
+
xs: "size-3",
|
|
4
|
+
sm: "size-4",
|
|
5
|
+
md: "size-5",
|
|
6
|
+
lg: "size-6",
|
|
7
|
+
xl: "size-8"
|
|
8
|
+
};
|
|
9
|
+
const COLOR = {
|
|
10
|
+
current: "text-current",
|
|
11
|
+
brand: "text-brand-primary",
|
|
12
|
+
muted: "text-fg-muted",
|
|
13
|
+
inverse: "text-fg-inverse"
|
|
14
|
+
};
|
|
15
|
+
function Spinner({
|
|
16
|
+
size = "md",
|
|
17
|
+
color = "current",
|
|
18
|
+
label = "Carregando\u2026",
|
|
19
|
+
className = ""
|
|
20
|
+
}) {
|
|
21
|
+
return /* @__PURE__ */ React.createElement("span", { role: "status", "aria-label": label, className: "inline-flex" }, /* @__PURE__ */ React.createElement(
|
|
22
|
+
"svg",
|
|
23
|
+
{
|
|
24
|
+
className: ["animate-spin", SIZE[size], COLOR[color], className].join(" "),
|
|
25
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
26
|
+
fill: "none",
|
|
27
|
+
viewBox: "0 0 24 24",
|
|
28
|
+
"aria-hidden": "true"
|
|
29
|
+
},
|
|
30
|
+
/* @__PURE__ */ React.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "3" }),
|
|
31
|
+
/* @__PURE__ */ React.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
32
|
+
), /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, label));
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
Spinner
|
|
36
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
interface StepProgressProps {
|
|
4
|
+
/** Zero-based current step index */
|
|
5
|
+
current: number;
|
|
6
|
+
/** Total number of steps */
|
|
7
|
+
total: number;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function StepProgress({ current, total, className }: StepProgressProps): react.JSX.Element;
|
|
11
|
+
|
|
12
|
+
export { StepProgress, type StepProgressProps };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "../chunk-ORMEWXMH.js";
|
|
2
|
+
function StepProgress({ current, total, className = "" }) {
|
|
3
|
+
const pct = Math.round((current + 1) / total * 100);
|
|
4
|
+
return /* @__PURE__ */ React.createElement(
|
|
5
|
+
"div",
|
|
6
|
+
{
|
|
7
|
+
className: ["w-full h-1.5 rounded-full overflow-hidden [background:var(--border-subtle)]", className].join(" "),
|
|
8
|
+
role: "progressbar",
|
|
9
|
+
"aria-valuenow": current + 1,
|
|
10
|
+
"aria-valuemin": 1,
|
|
11
|
+
"aria-valuemax": total
|
|
12
|
+
},
|
|
13
|
+
/* @__PURE__ */ React.createElement(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
className: "h-full rounded-full transition-all duration-300 ease-out [background:var(--brand-primary)]",
|
|
17
|
+
style: { width: `${pct}%` }
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
StepProgress
|
|
24
|
+
};
|