@cakejp/design-system 0.16.0 → 0.17.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/CHANGELOG.md +58 -0
- package/CLAUDE.md +1 -0
- package/bin/init.js +29 -6
- package/contracts/components.json +42 -7
- package/contracts/composition.json +8 -2
- package/contracts/rules.json +5 -1
- package/contracts/screen-patterns.json +1 -1
- package/dist/components/ec/_mypage-menu-data.js +166 -0
- package/dist/components/ec/admin-shell.js +202 -0
- package/dist/components/ec/anniversary-card.js +63 -0
- package/dist/components/ec/cake-logo.js +38 -0
- package/dist/components/ec/chart-controls.js +91 -0
- package/dist/components/ec/countdown-timer.js +50 -0
- package/dist/components/ec/coupon-card.js +136 -0
- package/dist/components/ec/delivery-calendar.js +105 -0
- package/dist/components/ec/mypage-shell.js +98 -0
- package/dist/components/ec/order-section.js +53 -0
- package/dist/components/ec/order-summary.js +78 -0
- package/dist/components/ec/payment-method.js +81 -0
- package/dist/components/ec/product-card.js +235 -0
- package/dist/components/ec/product-carousel.js +106 -0
- package/dist/components/ec/product-cta.js +80 -0
- package/dist/components/ec/product-detail-bar.js +86 -0
- package/dist/components/ec/product-detail-sidebar.js +296 -0
- package/dist/components/ec/product-list-item.js +266 -0
- package/dist/components/ec/product-option.js +165 -0
- package/dist/components/ec/rating-stars.js +74 -0
- package/dist/components/ec/review-card.js +126 -0
- package/dist/components/ec/review-form.js +181 -0
- package/dist/components/ec/review-summary.js +95 -0
- package/dist/components/ec/shop-card.js +179 -0
- package/dist/components/ec/stat-card.js +50 -0
- package/dist/components/foundations/accordion.js +67 -0
- package/dist/components/foundations/alert-dialog.js +165 -0
- package/dist/components/foundations/alert.js +218 -0
- package/dist/components/foundations/aspect-ratio.js +10 -0
- package/dist/components/foundations/avatar.js +58 -0
- package/dist/components/foundations/badge.js +54 -0
- package/dist/components/foundations/breadcrumb.js +104 -0
- package/dist/components/foundations/button.js +99 -0
- package/dist/components/foundations/calendar.js +173 -0
- package/dist/components/foundations/card.js +109 -0
- package/dist/components/foundations/checkbox-card.js +111 -0
- package/dist/components/foundations/checkbox-group.js +92 -0
- package/dist/components/foundations/checkbox.js +90 -0
- package/dist/components/foundations/chip-variants.js +41 -0
- package/dist/components/foundations/collapsible.js +34 -0
- package/dist/components/foundations/command.js +171 -0
- package/dist/components/foundations/context-menu.js +225 -0
- package/dist/components/foundations/data-table.js +59 -0
- package/dist/components/foundations/dialog.js +148 -0
- package/dist/components/foundations/drawer.js +129 -0
- package/dist/components/foundations/dropdown-menu.js +232 -0
- package/dist/components/foundations/field.js +150 -0
- package/dist/components/foundations/file-input.js +116 -0
- package/dist/components/foundations/form.js +101 -0
- package/dist/components/foundations/hover-card.js +41 -0
- package/dist/components/foundations/icon-badge.js +41 -0
- package/dist/components/foundations/input.js +74 -0
- package/dist/components/foundations/label.js +29 -0
- package/dist/components/foundations/menubar.js +252 -0
- package/dist/components/foundations/navigation-menu.js +171 -0
- package/dist/components/foundations/pagination.js +120 -0
- package/dist/components/foundations/popover.js +45 -0
- package/dist/components/foundations/progress.js +34 -0
- package/dist/components/foundations/radio-group.js +134 -0
- package/dist/components/foundations/responsive-dialog.js +76 -0
- package/dist/components/foundations/scroll-area.js +62 -0
- package/dist/components/foundations/select.js +190 -0
- package/dist/components/foundations/separator.js +27 -0
- package/dist/components/foundations/sheet.js +130 -0
- package/dist/components/foundations/skeleton.js +15 -0
- package/dist/components/foundations/skip-link.js +27 -0
- package/dist/components/foundations/slider.js +81 -0
- package/dist/components/foundations/social-icon.js +36 -0
- package/dist/components/foundations/sonner.js +49 -0
- package/dist/components/foundations/spinner.js +28 -0
- package/dist/components/foundations/switch.js +54 -0
- package/dist/components/foundations/table.js +115 -0
- package/dist/components/foundations/tabs.js +102 -0
- package/dist/components/foundations/textarea.js +65 -0
- package/dist/components/foundations/toggle-group.js +107 -0
- package/dist/components/foundations/toggle.js +44 -0
- package/dist/components/foundations/tooltip.js +56 -0
- package/dist/components/primitives/admin-header.js +31 -0
- package/dist/components/primitives/admin-side-nav.js +135 -0
- package/dist/components/primitives/banner-carousel.js +97 -0
- package/dist/components/primitives/bottom-tab-bar.js +81 -0
- package/dist/components/primitives/bulk-action-bar.js +27 -0
- package/dist/components/primitives/category-scroll.js +110 -0
- package/dist/components/primitives/category-shortcuts.js +66 -0
- package/dist/components/primitives/chat-composer.js +141 -0
- package/dist/components/primitives/chip.js +123 -0
- package/dist/components/primitives/coach-mark.js +102 -0
- package/dist/components/primitives/combobox.js +88 -0
- package/dist/components/primitives/container.js +50 -0
- package/dist/components/primitives/content-carousel.js +144 -0
- package/dist/components/primitives/date-picker.js +175 -0
- package/dist/components/primitives/empty-state.js +32 -0
- package/dist/components/primitives/error-state.js +115 -0
- package/dist/components/primitives/filter-bar.js +144 -0
- package/dist/components/primitives/footer.js +247 -0
- package/dist/components/primitives/form-field.js +38 -0
- package/dist/components/primitives/funnel-shell.js +99 -0
- package/dist/components/primitives/header.js +257 -0
- package/dist/components/primitives/image-carousel.js +156 -0
- package/dist/components/primitives/image-gallery.js +177 -0
- package/dist/components/primitives/image-input.js +207 -0
- package/dist/components/primitives/image-uploader.js +69 -0
- package/dist/components/primitives/kebab-menu.js +40 -0
- package/dist/components/primitives/list-item.js +80 -0
- package/dist/components/primitives/menu-drawer.js +154 -0
- package/dist/components/primitives/multi-select.js +93 -0
- package/dist/components/primitives/notification-badge.js +61 -0
- package/dist/components/primitives/notification-list.js +72 -0
- package/dist/components/primitives/number-input.js +235 -0
- package/dist/components/primitives/price-display.js +101 -0
- package/dist/components/primitives/progress-steps.js +62 -0
- package/dist/components/primitives/search-bar.js +81 -0
- package/dist/components/primitives/search-panel.js +43 -0
- package/dist/components/primitives/section-header.js +148 -0
- package/dist/components/primitives/section-nav.js +85 -0
- package/dist/components/primitives/section.js +78 -0
- package/dist/components/primitives/share-buttons.js +102 -0
- package/dist/components/primitives/side-nav.js +98 -0
- package/dist/components/primitives/social-login-button.js +53 -0
- package/dist/components/primitives/standard-page-shell.js +34 -0
- package/dist/components/primitives/status-count-tabs.js +42 -0
- package/dist/components/primitives/sticky-action-bar.js +26 -0
- package/dist/components/primitives/sub-nav.js +67 -0
- package/dist/components/primitives/tag.js +57 -0
- package/dist/components/primitives/timeline.js +55 -0
- package/dist/components/primitives/workspace-shell.js +57 -0
- package/dist/index.css +1 -1
- package/dist/index.js +22961 -13130
- package/dist/lib/field-labelling.js +29 -0
- package/dist/lib/focus-ring.js +6 -0
- package/dist/lib/pagination-range.js +42 -0
- package/dist/lib/use-value-length.js +63 -0
- package/dist/lib/utils.js +33 -0
- package/dist/types/components/foundations/accordion.d.ts +8 -1
- package/dist/types/components/foundations/data-table.d.ts +6 -1
- package/dist/types/components/foundations/slider.d.ts +13 -1
- package/dist/types/components/primitives/admin-header.d.ts +10 -0
- package/dist/types/components/primitives/admin-side-nav.d.ts +18 -0
- package/dist/types/components/primitives/combobox.d.ts +9 -1
- package/dist/types/components/primitives/menu-drawer.d.ts +0 -16
- package/dist/types/components/primitives/multi-select.d.ts +9 -1
- package/dist/types/lib/field-labelling.d.ts +66 -0
- package/package.json +8 -4
- package/scripts/codemod/README.md +9 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as a from "react";
|
|
2
|
+
const n = a.createContext(null);
|
|
3
|
+
function t() {
|
|
4
|
+
return a.useContext(n);
|
|
5
|
+
}
|
|
6
|
+
function d(r, e) {
|
|
7
|
+
if (!e) return {};
|
|
8
|
+
const i = [e.descriptionId, e.errorId].filter(Boolean).join(" ");
|
|
9
|
+
return {
|
|
10
|
+
id: r.id ?? e.controlId,
|
|
11
|
+
// aria-label が明示されていれば labelledby は当てない(二重命名を避ける)
|
|
12
|
+
"aria-labelledby": r["aria-labelledby"] ?? (r["aria-label"] ? void 0 : e.labelId),
|
|
13
|
+
"aria-describedby": r["aria-describedby"] ?? (i || void 0)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function o(r, e) {
|
|
17
|
+
if (!e) return {};
|
|
18
|
+
const i = [e.descriptionId, e.errorId].filter(Boolean).join(" ");
|
|
19
|
+
return {
|
|
20
|
+
id: r.id ?? e.controlId,
|
|
21
|
+
"aria-describedby": r["aria-describedby"] ?? (i || void 0)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
n as FieldLabellingContext,
|
|
26
|
+
d as resolveFieldAria,
|
|
27
|
+
o as resolveNativeFieldAria,
|
|
28
|
+
t as useFieldLabelling
|
|
29
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const i = "focus-visible:border-[var(--Focus-High-Emphasis)] focus-visible:ring-[3px] focus-visible:ring-[var(--Focus-High-Emphasis)]/50", s = "focus-within:border-[var(--Focus-High-Emphasis)] focus-within:ring-[3px] focus-within:ring-[var(--Focus-High-Emphasis)]/50", o = "focus-visible:ring-[3px] focus-visible:ring-inset focus-visible:ring-[var(--Focus-High-Emphasis)]/50";
|
|
2
|
+
export {
|
|
3
|
+
i as FOCUS_RING,
|
|
4
|
+
o as FOCUS_RING_INSET,
|
|
5
|
+
s as FOCUS_RING_WITHIN
|
|
6
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function p({
|
|
2
|
+
currentPage: f,
|
|
3
|
+
totalPages: g,
|
|
4
|
+
siblingCount: c = 1
|
|
5
|
+
}) {
|
|
6
|
+
const t = Math.max(0, Math.floor(g));
|
|
7
|
+
if (t === 0) return [];
|
|
8
|
+
const n = Math.max(0, Math.floor(c)), e = Math.min(t, Math.max(1, Math.floor(f))), m = n * 2 + 5;
|
|
9
|
+
if (t <= m)
|
|
10
|
+
return Array.from({ length: t }, (r, i) => i + 1);
|
|
11
|
+
const s = Math.max(e - n, 1), l = Math.min(e + n, t), a = s > 2, h = l < t - 1, o = n * 2 + 3;
|
|
12
|
+
if (!a && h)
|
|
13
|
+
return [
|
|
14
|
+
...Array.from({ length: o }, (r, i) => i + 1),
|
|
15
|
+
"ellipsis",
|
|
16
|
+
t
|
|
17
|
+
];
|
|
18
|
+
if (a && !h) {
|
|
19
|
+
const r = t - o + 1;
|
|
20
|
+
return [
|
|
21
|
+
1,
|
|
22
|
+
"ellipsis",
|
|
23
|
+
...Array.from(
|
|
24
|
+
{ length: o },
|
|
25
|
+
(i, M) => r + M
|
|
26
|
+
)
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
return [
|
|
30
|
+
1,
|
|
31
|
+
"ellipsis",
|
|
32
|
+
...Array.from(
|
|
33
|
+
{ length: l - s + 1 },
|
|
34
|
+
(r, i) => s + i
|
|
35
|
+
),
|
|
36
|
+
"ellipsis",
|
|
37
|
+
t
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
p as getPaginationRange
|
|
42
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as u from "react";
|
|
2
|
+
function a(e, c) {
|
|
3
|
+
if (typeof e == "function") {
|
|
4
|
+
const r = e(c);
|
|
5
|
+
return typeof r == "function" ? r : void 0;
|
|
6
|
+
}
|
|
7
|
+
e && typeof e == "object" && (e.current = c);
|
|
8
|
+
}
|
|
9
|
+
function y(e, c) {
|
|
10
|
+
const r = Object.getOwnPropertyDescriptor(e, "value"), i = Object.getOwnPropertyDescriptor(
|
|
11
|
+
Object.getPrototypeOf(e),
|
|
12
|
+
"value"
|
|
13
|
+
), t = r ?? i;
|
|
14
|
+
if (!t?.get || !t.set || t.configurable === !1)
|
|
15
|
+
return;
|
|
16
|
+
const l = function() {
|
|
17
|
+
return t.get.call(this);
|
|
18
|
+
}, s = function(n) {
|
|
19
|
+
t.set.call(this, n), c();
|
|
20
|
+
};
|
|
21
|
+
return Object.defineProperty(e, "value", {
|
|
22
|
+
configurable: !0,
|
|
23
|
+
enumerable: t.enumerable,
|
|
24
|
+
get: l,
|
|
25
|
+
set: s
|
|
26
|
+
}), () => {
|
|
27
|
+
const n = Object.getOwnPropertyDescriptor(e, "value");
|
|
28
|
+
n?.get !== l || n.set !== s || (r ? Object.defineProperty(e, "value", r) : Reflect.deleteProperty(e, "value"));
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function O({
|
|
32
|
+
enabled: e,
|
|
33
|
+
value: c,
|
|
34
|
+
defaultValue: r,
|
|
35
|
+
forwardedRef: i
|
|
36
|
+
}) {
|
|
37
|
+
const t = c !== void 0, l = u.useRef(null), s = u.useRef(void 0), n = u.useRef(void 0), [g, v] = u.useState(
|
|
38
|
+
() => r != null ? String(r).length : 0
|
|
39
|
+
), f = u.useCallback(() => {
|
|
40
|
+
const o = l.current;
|
|
41
|
+
o && v(o.value.length);
|
|
42
|
+
}, []), b = u.useCallback(
|
|
43
|
+
(o) => {
|
|
44
|
+
if (s.current?.(), s.current = void 0, l.current = o, !o) {
|
|
45
|
+
const p = n.current;
|
|
46
|
+
n.current = void 0, p ? p() : a(i, null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
n.current = a(i, o), e && !t && (s.current = y(o, f));
|
|
50
|
+
},
|
|
51
|
+
[e, i, t, f]
|
|
52
|
+
);
|
|
53
|
+
return u.useLayoutEffect(() => {
|
|
54
|
+
!e || t || f();
|
|
55
|
+
}), {
|
|
56
|
+
ref: b,
|
|
57
|
+
length: t ? String(c ?? "").length : g,
|
|
58
|
+
syncFromDom: f
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
O as useValueLength
|
|
63
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { clsx as t } from "clsx";
|
|
2
|
+
import { extendTailwindMerge as e } from "tailwind-merge";
|
|
3
|
+
const p = [
|
|
4
|
+
"typo-heading-5xl",
|
|
5
|
+
"typo-heading-4xl",
|
|
6
|
+
"typo-heading-3xl",
|
|
7
|
+
"typo-heading-2xl",
|
|
8
|
+
"typo-heading-xl",
|
|
9
|
+
"typo-heading-lg",
|
|
10
|
+
"typo-heading-md",
|
|
11
|
+
"typo-heading-sm",
|
|
12
|
+
"typo-body-lg",
|
|
13
|
+
"typo-body-md",
|
|
14
|
+
"typo-body-sm",
|
|
15
|
+
"typo-body-xs",
|
|
16
|
+
"typo-label-lg",
|
|
17
|
+
"typo-label-md",
|
|
18
|
+
"typo-label-sm",
|
|
19
|
+
"typo-label-xs"
|
|
20
|
+
], y = e({
|
|
21
|
+
extend: {
|
|
22
|
+
classGroups: {
|
|
23
|
+
"cake-typography": p
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
function n(...o) {
|
|
28
|
+
return y(t(o));
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
p as TYPO_PRESET_CLASS_NAMES,
|
|
32
|
+
n as cn
|
|
33
|
+
};
|
|
@@ -2,6 +2,13 @@ import * as React from "react";
|
|
|
2
2
|
import { Accordion as AccordionPrimitive } from "radix-ui";
|
|
3
3
|
declare function Accordion({ ...props }: React.ComponentProps<typeof AccordionPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
declare function AccordionItem({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
|
|
5
|
+
interface AccordionTriggerProps extends React.ComponentProps<typeof AccordionPrimitive.Trigger> {
|
|
6
|
+
/**
|
|
7
|
+
* 見出し要素のレベル(既定: 3 = radix Accordion.Header の既定 <h3>)。
|
|
8
|
+
* ページの見出し階層に合わせて変更する(例: サイドバーのカテゴリナビで h2)。
|
|
9
|
+
*/
|
|
10
|
+
headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
11
|
+
}
|
|
12
|
+
declare function AccordionTrigger({ className, children, headingLevel, ...props }: AccordionTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
6
13
|
declare function AccordionContent({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
|
|
7
14
|
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
|
@@ -91,7 +91,7 @@ declare function DataTableInputCell({ className, value, onChange, placeholder, t
|
|
|
91
91
|
type?: string;
|
|
92
92
|
name?: string;
|
|
93
93
|
}): import("react/jsx-runtime").JSX.Element;
|
|
94
|
-
declare function DataTableSelectCell({ className, value, onValueChange, options, placeholder, ...props }: Omit<React.ComponentProps<"td">, "children" | "width" | "align"> & {
|
|
94
|
+
declare function DataTableSelectCell({ className, value, onValueChange, options, placeholder, "aria-label": ariaLabel, ...props }: Omit<React.ComponentProps<"td">, "children" | "width" | "align"> & {
|
|
95
95
|
value?: string;
|
|
96
96
|
onValueChange?: (value: string) => void;
|
|
97
97
|
options: Array<{
|
|
@@ -99,6 +99,11 @@ declare function DataTableSelectCell({ className, value, onValueChange, options,
|
|
|
99
99
|
label: string;
|
|
100
100
|
}>;
|
|
101
101
|
placeholder?: string;
|
|
102
|
+
/**
|
|
103
|
+
* セレクトのアクセシブルネーム(日本語)。表の見出しに相当する語を渡す。
|
|
104
|
+
* 未指定時は placeholder を名前に使う(`role="combobox"` は内容から名前が付かないため)。
|
|
105
|
+
*/
|
|
106
|
+
"aria-label"?: string;
|
|
102
107
|
}): import("react/jsx-runtime").JSX.Element;
|
|
103
108
|
declare function DataTableNumberCell({ className, children, ...props }: Omit<React.ComponentProps<"td">, "width" | "align">): import("react/jsx-runtime").JSX.Element;
|
|
104
109
|
export { DataTable, DataTableTable, DataTableHeader, DataTableBody, DataTableRow, DataTableHead, DataTableCell, DataTableAvatarCell, DataTableImageCell, DataTableLinkCell, DataTableCheckboxCell, DataTableActionCell, DataTableInputCell, DataTableSelectCell, DataTableNumberCell, DataTableDragHandleCell, DataTableBulkActions, DataTableSectionRow, DataTableAddRow, DataTableEmptyState, };
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Slider as SliderPrimitive } from "radix-ui";
|
|
3
|
-
|
|
3
|
+
export interface SliderProps extends React.ComponentProps<typeof SliderPrimitive.Root> {
|
|
4
|
+
/**
|
|
5
|
+
* つまみ(thumb)ごとのアクセシブルネーム(日本語)。
|
|
6
|
+
*
|
|
7
|
+
* `role="slider"` を持つのは **つまみ側**なので、名前はつまみに付ける必要がある。
|
|
8
|
+
* 未指定のときは次の順で決まる(issue #202):
|
|
9
|
+
* 1. `aria-label` … つまみが 2 つ以上なら「(下限)」「(上限)」を補って区別する
|
|
10
|
+
* 2. `FormField` 配下ならそのラベル
|
|
11
|
+
* 3. `aria-labelledby`
|
|
12
|
+
*/
|
|
13
|
+
thumbLabels?: string[];
|
|
14
|
+
}
|
|
15
|
+
declare function Slider({ className, defaultValue, value, min, max, thumbLabels, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...props }: SliderProps): import("react/jsx-runtime").JSX.Element;
|
|
4
16
|
export { Slider };
|
|
@@ -15,6 +15,16 @@ export interface AdminHeaderProps {
|
|
|
15
15
|
* のレール(--Z-Sticky = 30)が始まる=ヘッダーが最前面・全幅で、レールはヘッダー帯に重ならない。
|
|
16
16
|
* 「{shopName}管理」のような文言合成は行わない(利用側が `brand` に組み立てて渡す)。
|
|
17
17
|
*
|
|
18
|
+
* ### ページタイトルを複製しない
|
|
19
|
+
*
|
|
20
|
+
* ページ名の正は本文の h1(`AdminShell` の `title`)。ヘッダーにはブランド・パンくず(現在地の文脈)・
|
|
21
|
+
* グローバル操作を置き、同じページ名をヘッダーにも出さない。置くものが無ければヘッダーバー自体を省いてよい。
|
|
22
|
+
*
|
|
23
|
+
* ### 水平 padding は本文コンテナの gutter と揃える
|
|
24
|
+
*
|
|
25
|
+
* `px-4 @md:px-6` は `AdminShell` の `<main>`(`p-4 @md:p-6`)と同値。ヘッダー内要素の左端と
|
|
26
|
+
* 本文 h1 の左端が同じ面に乗る。片方だけ変えるとズレが視認されるので、変更するときは両方揃えて変える。
|
|
27
|
+
*
|
|
18
28
|
* ### インポート
|
|
19
29
|
* ```tsx
|
|
20
30
|
* import { AdminHeader } from '../../components/primitives/admin-header'
|
|
@@ -48,6 +48,24 @@ export interface AdminSideNavProps {
|
|
|
48
48
|
* SP は制御された左スライドドロワー(サブメニューはアコーディオン)で表示する。
|
|
49
49
|
* メニュー定義・文言・データは全て `items` prop で受け取り、部品側には焼き込まない。
|
|
50
50
|
*
|
|
51
|
+
* ### サイドバーは 1 枚のパネルとして読ませる
|
|
52
|
+
*
|
|
53
|
+
* ヘッダー行(SP ドロワー上部の見出し + 閉じるボタン)に **border-bottom を引かない**。
|
|
54
|
+
* フッター(ユーザーブロック・ヘルプ導線等)を設ける場合も **上に border-top を引かない**。
|
|
55
|
+
* サイドバー内部を横線で区切るとパネルが分割されて見え、ナビの一体感が失われる。分離は余白が担う。
|
|
56
|
+
* 画面全体で見える横罫線は ①サイドバー右端の縦線 ②コンテンツヘッダー下の横線 の 2 本に絞り、
|
|
57
|
+
* サイドバー内で横線を引くと 2 本が十字に交差して見える(正しくは T 字で突き当たる)。
|
|
58
|
+
*
|
|
59
|
+
* ### 折りたたみトリガーはサイドバー自身に置く
|
|
60
|
+
*
|
|
61
|
+
* サイドバーに開閉(折りたたみ)を持たせる場合、トリガーは **サイドバー内ヘッダー行の右端** に置く。
|
|
62
|
+
* コンテンツヘッダーの左端に置くと、動かす対象と操作する場所が離れて所属が読めなくなる。
|
|
63
|
+
*
|
|
64
|
+
* ### 項目高は 44px を確保する
|
|
65
|
+
*
|
|
66
|
+
* メイン項目・サブメニュー項目とも 44px(WCAG 2.5.5 の最小ターゲット)以上にする。
|
|
67
|
+
* 行高が小さいテキストで縦 padding だけに頼ると割り込むため、`min-h-11` で下限を固定する。
|
|
68
|
+
*
|
|
51
69
|
* ### インポート
|
|
52
70
|
* ```tsx
|
|
53
71
|
* import { AdminSideNav } from '../../components/primitives/admin-side-nav'
|
|
@@ -19,6 +19,14 @@ export interface ComboboxProps {
|
|
|
19
19
|
"aria-invalid"?: boolean;
|
|
20
20
|
/** FieldError / FieldDescription の id */
|
|
21
21
|
"aria-describedby"?: string;
|
|
22
|
+
/**
|
|
23
|
+
* トリガーのアクセシブルネーム(日本語)。
|
|
24
|
+
* `role="combobox"` は内容からは名前が付かないため、FormField の外で単体利用する
|
|
25
|
+
* ときはこれか `aria-labelledby` を指定する(未指定時は placeholder を名前に使う)。
|
|
26
|
+
*/
|
|
27
|
+
"aria-label"?: string;
|
|
28
|
+
/** ラベル要素の id を直接指定する場合 */
|
|
29
|
+
"aria-labelledby"?: string;
|
|
22
30
|
}
|
|
23
|
-
declare function Combobox({ options, value, onValueChange, placeholder, searchPlaceholder, emptyLabel, disabled, className, id, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, }: ComboboxProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
declare function Combobox({ options, value, onValueChange, placeholder, searchPlaceholder, emptyLabel, disabled, className, id, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, }: ComboboxProps): import("react/jsx-runtime").JSX.Element;
|
|
24
32
|
export { Combobox };
|
|
@@ -55,21 +55,5 @@ export interface MenuDrawerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
55
55
|
/** ログインリンクのhref(デフォルト: /security/login_link/) */
|
|
56
56
|
loginHref?: string;
|
|
57
57
|
}
|
|
58
|
-
/**
|
|
59
|
-
* メニュードロワー
|
|
60
|
-
*
|
|
61
|
-
* ハンバーガーメニューの中身。本番サイドナビと同じ構造。
|
|
62
|
-
* Figma: Menu - Contents
|
|
63
|
-
*
|
|
64
|
-
* ### AI 向け使用ルール
|
|
65
|
-
*
|
|
66
|
-
* - ログイン時: `<MenuDrawer isLoggedIn userName="田中花子" sections={[...]} />`
|
|
67
|
-
* - 未ログイン: `<MenuDrawer isLoggedIn={false} sections={[...]} />`
|
|
68
|
-
* - Drawer コンポーネントの中に配置して使用
|
|
69
|
-
* - セクションの `border` を true にするとセクション上部に区切り線を表示
|
|
70
|
-
* - アイテムの `hasChildren` を true にすると右矢印(ドリルダウン)を表示
|
|
71
|
-
* - カテゴリ系アイテムは `thumb` にサムネイル画像URLを指定
|
|
72
|
-
* - `itemsExtra` は「すべて表示」で展開されるアイテム群
|
|
73
|
-
*/
|
|
74
58
|
declare function MenuDrawer({ userName, isLoggedIn, hideLoginLink, sections, banners, onClose, onLogin, loginHref, className, ...props }: MenuDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
75
59
|
export { MenuDrawer };
|
|
@@ -19,6 +19,14 @@ export interface MultiSelectProps {
|
|
|
19
19
|
"aria-invalid"?: boolean;
|
|
20
20
|
/** FieldError / FieldDescription の id */
|
|
21
21
|
"aria-describedby"?: string;
|
|
22
|
+
/**
|
|
23
|
+
* トリガーのアクセシブルネーム(日本語)。
|
|
24
|
+
* `role="combobox"` は内容からは名前が付かないため、FormField の外で単体利用する
|
|
25
|
+
* ときはこれか `aria-labelledby` を指定する(未指定時は placeholder を名前に使う)。
|
|
26
|
+
*/
|
|
27
|
+
"aria-label"?: string;
|
|
28
|
+
/** ラベル要素の id を直接指定する場合 */
|
|
29
|
+
"aria-labelledby"?: string;
|
|
22
30
|
}
|
|
23
|
-
declare function MultiSelect({ options, value, onValueChange, placeholder, searchPlaceholder, emptyLabel, disabled, className, id, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
declare function MultiSelect({ options, value, onValueChange, placeholder, searchPlaceholder, emptyLabel, disabled, className, id, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
24
32
|
export { MultiSelect };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## フィールドのラベル関連付け(DS 全体の方針 / issue #202)
|
|
3
|
+
*
|
|
4
|
+
* Radix ベースのコントロール(Select / Switch / Checkbox / Slider 等)は
|
|
5
|
+
* `<button>` や `<span role="...">` として描画されるため、**隣に `<Label htmlFor>` を
|
|
6
|
+
* 置いてもアクセシブルネームにならない**(`<label for>` が名前を与えるのは
|
|
7
|
+
* labelable な要素だけで、`<button>` は対象外)。
|
|
8
|
+
*
|
|
9
|
+
* そこで DS は次の方針を採る:
|
|
10
|
+
*
|
|
11
|
+
* 1. フィールドのラッパー(`FormField`)がラベル要素に **id を採番**し、
|
|
12
|
+
* その id を context で配下のコントロールへ渡す。
|
|
13
|
+
* 2. コントロール側は `aria-labelledby` を **既定値として** その id にする。
|
|
14
|
+
* 利用側が `aria-label` / `aria-labelledby` を明示した場合はそちらを優先する。
|
|
15
|
+
* 3. ラッパー無しで単体利用するときは、利用側が `aria-label`(日本語)を書く。
|
|
16
|
+
*
|
|
17
|
+
* `<label for>` が有効なネイティブ入力(Input / Textarea)は従来どおり
|
|
18
|
+
* `htmlFor` ↔ `id` の関連付けで足りるため、context の `controlId` を使う。
|
|
19
|
+
*/
|
|
20
|
+
import * as React from "react";
|
|
21
|
+
export interface FieldLabellingValue {
|
|
22
|
+
/** ラベル要素の id。コントロールの aria-labelledby 既定値になる */
|
|
23
|
+
labelId: string;
|
|
24
|
+
/** コントロールに割り当てる id(ネイティブ入力の htmlFor 対応用) */
|
|
25
|
+
controlId: string;
|
|
26
|
+
/** 説明文の id。存在するときだけ設定される */
|
|
27
|
+
descriptionId?: string;
|
|
28
|
+
/** エラーメッセージの id。存在するときだけ設定される */
|
|
29
|
+
errorId?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* ラッパー(FormField 等)が配下のコントロールへ id を渡す context。
|
|
33
|
+
* Provider は利用側で `<FieldLabellingContext.Provider value={...}>` として使う
|
|
34
|
+
* (このファイルはコンポーネントを export しない = fast refresh の制約に合わせる)。
|
|
35
|
+
*/
|
|
36
|
+
declare const FieldLabellingContext: React.Context<FieldLabellingValue>;
|
|
37
|
+
/** ラッパー内かどうかを問わず使える。ラッパー外では null。 */
|
|
38
|
+
declare function useFieldLabelling(): FieldLabellingValue | null;
|
|
39
|
+
/**
|
|
40
|
+
* Radix トリガー系コントロール向けの aria 属性を解決する。
|
|
41
|
+
*
|
|
42
|
+
* 利用側の明示指定(aria-label / aria-labelledby / id / aria-describedby)を必ず優先し、
|
|
43
|
+
* 何も指定が無いときだけラッパーの id を当てる。
|
|
44
|
+
*/
|
|
45
|
+
declare function resolveFieldAria(props: {
|
|
46
|
+
id?: string;
|
|
47
|
+
"aria-label"?: string;
|
|
48
|
+
"aria-labelledby"?: string;
|
|
49
|
+
"aria-describedby"?: string;
|
|
50
|
+
}, field: FieldLabellingValue | null): {
|
|
51
|
+
id?: string;
|
|
52
|
+
"aria-labelledby"?: string;
|
|
53
|
+
"aria-describedby"?: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* ネイティブ入力(Input / Textarea)向け。
|
|
57
|
+
* 名前は `<label for>` ↔ `id` で付くので、ここでは id と説明の関連付けだけ行う。
|
|
58
|
+
*/
|
|
59
|
+
declare function resolveNativeFieldAria(props: {
|
|
60
|
+
id?: string;
|
|
61
|
+
"aria-describedby"?: string;
|
|
62
|
+
}, field: FieldLabellingValue | null): {
|
|
63
|
+
id?: string;
|
|
64
|
+
"aria-describedby"?: string;
|
|
65
|
+
};
|
|
66
|
+
export { FieldLabellingContext, useFieldLabelling, resolveFieldAria, resolveNativeFieldAria, };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cakejp/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cake.jp Design System — UI コンポーネント・カラートークン・タイポグラフィ",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"module": "./dist/index.js",
|
|
29
29
|
"types": "./dist/types/index.d.ts",
|
|
30
30
|
"bin": {
|
|
31
|
-
"cakejp-ds": "
|
|
31
|
+
"cakejp-ds": "bin/init.js"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
34
|
"CHANGELOG.md",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"scripts": {
|
|
81
81
|
"dev": "vite",
|
|
82
82
|
"build": "tsc -b && vite build",
|
|
83
|
-
"build:lib": "vite build --config vite.config.lib.ts && tsc --project tsconfig.lib.json && tsc-alias --project tsconfig.lib.json",
|
|
83
|
+
"build:lib": "vite build --config vite.config.lib.ts && node scripts/append-tailwind-source-manifest.mjs && tsc --project tsconfig.lib.json && tsc-alias --project tsconfig.lib.json",
|
|
84
84
|
"prepack": "npm run build:lib",
|
|
85
85
|
"prepare": "npm run build:lib",
|
|
86
86
|
"postinstall": "node ./bin/init.js postinstall",
|
|
@@ -181,5 +181,9 @@
|
|
|
181
181
|
"vite": "^7.3.1",
|
|
182
182
|
"vitest": "^4.1.0",
|
|
183
183
|
"zod": "^4.3.6"
|
|
184
|
-
}
|
|
184
|
+
},
|
|
185
|
+
"directories": {
|
|
186
|
+
"doc": "docs"
|
|
187
|
+
},
|
|
188
|
+
"author": ""
|
|
185
189
|
}
|
|
@@ -9,6 +9,15 @@ node scripts/codemod/v1-to-v2.mjs --dry ./src
|
|
|
9
9
|
node scripts/codemod/v1-to-v2.mjs ./src
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
ここに置いたファイル名がそのまま consumer 側の codemod 名になります(dispatch の
|
|
13
|
+
書き換えは不要)。`template.mjs` と `check-migration.mjs` は一覧から除外されます。
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx cakejp-ds codemod # 使える codemod 名の一覧
|
|
17
|
+
npx cakejp-ds codemod v1-to-v2 --dry ./src
|
|
18
|
+
npx cakejp-ds codemod v1-to-v2 ./src
|
|
19
|
+
```
|
|
20
|
+
|
|
12
21
|
正規表現ベースのため、必ずコミット済みの利用側で `--dry` を先に実行し、
|
|
13
22
|
適用後は `git diff` と ESLint の `@cakejp/design-system/eslint/deprecated`
|
|
14
23
|
で残件を確認してください。
|