@keyfunc/keybricks-ds 2.4.11 → 2.4.13

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.
@@ -1 +0,0 @@
1
- window.__KB_SRC__=Object.assign(window.__KB_SRC__||{},{"tabs/SegmentedControl.jsx":"import React from \"react\";\nimport { Icon } from \"../icons/Icon.jsx\";\nimport { CountBadge } from \"./Tabs.jsx\";\n\n/**\n * Segmented control — inset track, raised active segment. Switches views of the same data, applies instantly.\n * options: string[] | { label, icon?, disabled?, count?, showZero? }[] value/onChange by label\n * count draws a CountBadge 6px right of the label (hidden for 0 unless showZero — per option or on the control); the match stays by label.\n * size sm 28 | md 32 | lg 40 — omit it to inherit the region's tier · iconOnly hides labels (label becomes aria-label / title)\n * disabled greys the whole control · fullWidth stretches segments evenly\n * Keyboard: ← → move between enabled segments.\n */\nconst tierIcon = { width: \"var(--control-icon)\", height: \"var(--control-icon)\" };\nexport function SegmentedControl({ options = [], value, onChange, size, iconOnly, disabled, fullWidth, showZero, style }) {\n const opts = options.map((o) => (typeof o === \"string\" ? { label: o } : o));\n const enabled = opts.filter((o) => !o.disabled);\n const onKey = (e) => {\n if (e.key !== \"ArrowLeft\" && e.key !== \"ArrowRight\" || disabled || !enabled.length) return;\n e.preventDefault();\n const i = enabled.findIndex((o) => o.label === value);\n const n = e.key === \"ArrowRight\" ? enabled[(i + 1) % enabled.length] : enabled[(i - 1 + enabled.length) % enabled.length];\n onChange && onChange(n.label);\n };\n return (\n <div role=\"tablist\" data-size={size} aria-disabled={disabled || undefined} onKeyDown={onKey} style={{ display: fullWidth ? \"flex\" : \"inline-flex\", height: \"var(--control-h)\", padding: 2, gap: 2, background: \"var(--bg-inset)\", border: \"1px solid var(--border-control)\", borderRadius: \"var(--radius-md)\", boxSizing: \"border-box\", opacity: disabled ? .5 : 1, ...style }}>\n {opts.map((o) => {\n const is = value === o.label, off = disabled || o.disabled;\n return (\n <button key={o.label} type=\"button\" role=\"tab\" aria-selected={is} aria-label={iconOnly ? o.label : undefined} title={iconOnly ? o.label : undefined} disabled={off} tabIndex={is ? 0 : -1} data-ink={is || off ? undefined : \"\"}\n onClick={() => !off && onChange && onChange(o.label)}\n style={{ height: \"calc(var(--control-h) - 6px)\", padding: iconOnly ? \"0 calc(var(--control-px) - 4px)\" : \"0 calc(var(--control-px) - 2px)\", flex: fullWidth ? 1 : \"none\", justifyContent: \"center\", display: \"inline-flex\", alignItems: \"center\", gap: 6, borderRadius: \"var(--radius-sm)\", border: \"none\", cursor: off ? \"not-allowed\" : \"pointer\", background: is ? \"var(--bg-surface)\" : \"transparent\", boxShadow: is ? \"0 1px 2px rgba(0,0,0,.08)\" : \"none\", fontFamily: \"var(--font-sans)\", fontWeight: \"var(--weight-medium)\", fontSize: \"var(--control-text)\", lineHeight: \"var(--control-leading)\", letterSpacing: \"var(--control-tracking)\", color: is ? \"var(--text-heading)\" : \"var(--ink, var(--text-secondary))\", opacity: o.disabled && !disabled ? .45 : 1, whiteSpace: \"nowrap\", transition: \"var(--t-hover)\" }}>\n {o.icon ? <Icon name={o.icon} size={16} style={tierIcon} /> : null}{iconOnly ? null : o.label}{iconOnly ? null : <CountBadge count={o.count} selected={is} showZero={o.showZero ?? showZero} />}\n </button>\n );\n })}\n </div>\n );\n}\n","tabs/SegmentedControl.vue":"<script setup>\nimport { computed } from 'vue'\nimport Icon from '../icons/Icon.vue'\nimport CountBadge from './CountBadge.vue'\n// Segmented control — inset track, raised active segment. Switches views of the same data, applies instantly.\n// options: string[] | { label, icon?, disabled?, count?, showZero? }[] · v-model by label · count draws a CountBadge 6px right of the label (hidden for 0 unless showZero) · size sm 28 | md 32 | lg 40 — omit it to inherit the region's tier\n// iconOnly hides labels (label → aria-label/title) · disabled greys the control · fullWidth stretches segments · ← → keyboard.\nconst tierIcon = { width: 'var(--control-icon)', height: 'var(--control-icon)' }\nconst props = defineProps({ options: { type: Array, default: () => [] }, modelValue: String, size: String, iconOnly: Boolean, disabled: Boolean, fullWidth: Boolean, showZero: Boolean, style: Object })\nconst emit = defineEmits(['update:modelValue'])\nconst opts = computed(() => props.options.map(o => typeof o === 'string' ? { label: o } : o))\nconst enabled = computed(() => opts.value.filter(o => !o.disabled))\nconst pick = (o) => { if (!(props.disabled || o.disabled)) emit('update:modelValue', o.label) }\nfunction onKey(e) {\n if ((e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') || props.disabled || !enabled.value.length) return\n e.preventDefault()\n const i = enabled.value.findIndex(o => o.label === props.modelValue), n = enabled.value.length\n emit('update:modelValue', (e.key === 'ArrowRight' ? enabled.value[(i + 1) % n] : enabled.value[(i - 1 + n) % n]).label)\n}\n</script>\n<template>\n <div role=\"tablist\" :data-size=\"size\" :aria-disabled=\"disabled || undefined\" @keydown=\"onKey\" :style=\"{ display: fullWidth ? 'flex' : 'inline-flex', height: 'var(--control-h)', padding: '2px', gap: '2px', background: 'var(--bg-inset)', border: '1px solid var(--border-control)', borderRadius: 'var(--radius-md)', boxSizing: 'border-box', opacity: disabled ? .5 : 1, ...style }\">\n <button v-for=\"o in opts\" :key=\"o.label\" type=\"button\" role=\"tab\" :aria-selected=\"modelValue === o.label\" :aria-label=\"iconOnly ? o.label : undefined\" :title=\"iconOnly ? o.label : undefined\" :disabled=\"disabled || o.disabled\" :tabindex=\"modelValue === o.label ? 0 : -1\" :data-ink=\"modelValue === o.label || disabled || o.disabled ? undefined : ''\" @click=\"pick(o)\"\n :style=\"{ height: 'calc(var(--control-h) - 6px)', padding: iconOnly ? '0 calc(var(--control-px) - 4px)' : '0 calc(var(--control-px) - 2px)', flex: fullWidth ? 1 : 'none', justifyContent: 'center', display: 'inline-flex', alignItems: 'center', gap: '6px', borderRadius: 'var(--radius-sm)', border: 'none', cursor: (disabled || o.disabled) ? 'not-allowed' : 'pointer', background: modelValue === o.label ? 'var(--bg-surface)' : 'transparent', boxShadow: modelValue === o.label ? '0 1px 2px rgba(0,0,0,.08)' : 'none', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: modelValue === o.label ? 'var(--text-heading)' : 'var(--ink, var(--text-secondary))', opacity: o.disabled && !disabled ? .45 : 1, whiteSpace: 'nowrap', transition: 'var(--t-hover)' }\">\n <Icon v-if=\"o.icon\" :name=\"o.icon\" :size=\"16\" :style=\"tierIcon\" /><template v-if=\"!iconOnly\">{{ o.label }}<CountBadge :count=\"o.count\" :selected=\"modelValue === o.label\" :show-zero=\"o.showZero ?? showZero\" /></template>\n </button>\n </div>\n</template>\n","tabs/Tabs.jsx":"import React from \"react\";\n\n/* tabs: string[] | { label, count?, showZero? }[] — shared by Tabs, PanelTabs and PillTabs; active is matched by label. */\nconst norm = (tabs) => tabs.map((t) => (typeof t === \"string\" ? { label: t } : t));\n\n/** Underline tabs on a hairline baseline (Import/Export). Active = blue text + 2px blue underline. The bar is the region's bar height (sm 32 · md 40 · lg 44) with the tier's control text; omit `size` to inherit.\n * A tab's count renders as a CountBadge 6px right of the label (the badge stays neutral under the blue active tab). */\nexport function Tabs({ tabs = [], active, onChange, size, showZero, style }) {\n return (\n <div role=\"tablist\" data-size={size} style={{ display: \"flex\", gap: 4, borderBottom: \"1px solid var(--border-control)\", ...style }}>\n {norm(tabs).map((t) => {\n const is = t.label === active;\n return (\n <button key={t.label} type=\"button\" role=\"tab\" aria-selected={is} data-ink={is ? undefined : \"\"} onClick={() => onChange && onChange(t.label)}\n style={{ background: \"transparent\", border: \"none\", cursor: \"pointer\", height: \"var(--bar-h)\", boxSizing: \"border-box\", padding: \"0 var(--control-px)\", marginBottom: -1, borderBottom: is ? \"2px solid var(--action-primary)\" : \"2px solid transparent\", display: \"inline-flex\", alignItems: \"center\", gap: 6, fontFamily: \"var(--font-sans)\", fontWeight: \"var(--weight-medium)\", fontSize: \"var(--control-text)\", lineHeight: \"var(--control-leading)\", letterSpacing: \"var(--control-tracking)\", color: is ? \"var(--action-primary)\" : \"var(--ink, var(--text-body))\", whiteSpace: \"nowrap\" }}>\n {t.label}<CountBadge count={t.count} selected={is} showZero={t.showZero ?? showZero} />\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Panel tabs (Node Info · Calc Rules · Output Fields · SQL Preview): a lighter underline tab bar at the region's bar height with regular-weight control text. Put the panel in an sm region for the compact 32px/12px look. */\nexport function PanelTabs({ tabs = [], active, onChange, size, showZero, style }) {\n return (\n <div role=\"tablist\" data-size={size} style={{ display: \"flex\", borderBottom: \"1px solid var(--border-subtle)\", ...style }}>\n {norm(tabs).map((t) => {\n const is = t.label === active;\n return (\n <button key={t.label} type=\"button\" role=\"tab\" aria-selected={is} data-ink={is ? undefined : \"\"} onClick={() => onChange && onChange(t.label)}\n style={{ background: \"transparent\", border: \"none\", cursor: \"pointer\", height: \"var(--bar-h)\", boxSizing: \"border-box\", padding: \"0 var(--control-px)\", marginBottom: -1, borderBottom: is ? \"2px solid var(--action-primary)\" : \"2px solid transparent\", display: \"inline-flex\", alignItems: \"center\", gap: 6, fontFamily: \"var(--font-sans)\", fontSize: \"var(--control-text)\", lineHeight: \"var(--control-leading)\", letterSpacing: \"var(--control-tracking)\", color: is ? \"var(--action-primary)\" : \"var(--ink, var(--text-secondary))\", whiteSpace: \"nowrap\" }}>\n {t.label}<CountBadge count={t.count} selected={is} showZero={t.showZero ?? showZero} />\n </button>\n );\n })}\n </div>\n );\n}\n\n\n/* Count badge beside a segment / pill label: --count-h tall (sm 16 · md and lg 18), 6px sides, full radius, 12px tabular figures\n (digits are Latin, so the size is not bumped in CJK). The fill is the alpha wash --neutral-alpha-8, so it darkens whatever it sits on by the\n same step (white tab, #f5f5f5 active pill, dark theme); the text tells selected from unselected: --text-heading vs --text-body\n (a lighter grey fails 4.5:1 on a grey fill at 12px). Hidden for 0 or a missing count unless showZero, which draws a muted 0. */\nexport function CountBadge({ count, selected, showZero, style }) {\n const zero = count === 0 || count == null;\n if (zero && !showZero) return null;\n return <span aria-hidden=\"true\" style={{ display: \"inline-flex\", alignItems: \"center\", height: \"var(--count-h)\", padding: \"0 6px\", borderRadius: \"var(--radius-full)\", background: \"var(--neutral-alpha-8)\", color: zero ? \"var(--text-muted)\" : selected ? \"var(--text-heading)\" : \"var(--text-body)\", fontFamily: \"var(--font-sans)\", fontSize: 12, lineHeight: \"var(--count-h)\", fontWeight: \"var(--weight-medium)\", letterSpacing: 0, fontVariantNumeric: \"tabular-nums\", flexShrink: 0, ...style }}>{zero ? 0 : count}</span>;\n}\n/** Text pill filter tabs (For Review · To be Submitted · For Approval). Active = tinted pill. Pills are control-height (sm 28 · md 32 · lg 40); omit `size` to inherit.\n * tabs: string[] | { label, count?, showZero? }[] — a count draws a CountBadge 6px right of the label; active is matched by label. */\nexport function PillTabs({ tabs = [], active, onChange, size, showZero, style }) {\n return (\n <div role=\"tablist\" data-size={size} style={{ display: \"flex\", gap: \"var(--control-gap)\", ...style }}>\n {norm(tabs).map((t) => {\n const is = t.label === active;\n return (\n <button key={t.label} type=\"button\" role=\"tab\" aria-selected={is} data-ink={is ? undefined : \"\"} data-wash={is ? undefined : \"\"} onClick={() => onChange && onChange(t.label)}\n style={{ background: is ? \"var(--bg-active)\" : \"var(--wash, transparent)\", border: \"none\", cursor: \"pointer\", height: \"var(--control-h)\", padding: \"0 var(--control-px)\", borderRadius: \"var(--radius-md)\", display: \"inline-flex\", alignItems: \"center\", gap: 6, fontFamily: \"var(--font-sans)\", fontWeight: \"var(--weight-medium)\", fontSize: \"var(--control-text)\", lineHeight: \"var(--control-leading)\", letterSpacing: \"var(--control-tracking)\", color: is ? \"var(--text-heading)\" : \"var(--ink, var(--text-secondary))\", whiteSpace: \"nowrap\" }}>\n {t.label}<CountBadge count={t.count} selected={is} showZero={t.showZero ?? showZero} />\n </button>\n );\n })}\n </div>\n );\n}\n","tabs/Tabs.vue":"<script setup>\nimport { computed } from 'vue'\nimport CountBadge from './CountBadge.vue'\n// Underline tabs on a hairline baseline (Import/Export). Active = blue text + 2px blue underline. The bar is the region's bar height (sm 32 · md 40 · lg 44) with the tier's control text; omit `size` to inherit.\n// tabs: string[] | { label, count?, showZero? }[] — a count renders as a CountBadge 6px right of the label (neutral under the blue active tab); active is matched by label.\nconst props = defineProps({ tabs: { type: Array, default: () => [] }, active: String, size: String, showZero: Boolean, style: Object })\nconst emit = defineEmits(['change'])\nconst items = computed(() => props.tabs.map(t => typeof t === 'string' ? { label: t } : t))\n</script>\n<template>\n <div role=\"tablist\" :data-size=\"size\" :style=\"{ display: 'flex', gap: '4px', borderBottom: '1px solid var(--border-control)', ...style }\">\n <button v-for=\"t in items\" :key=\"t.label\" type=\"button\" role=\"tab\" :aria-selected=\"t.label === active\" :data-ink=\"t.label === active ? undefined : ''\" @click=\"emit('change', t.label)\"\n :style=\"{ background: 'transparent', border: 'none', cursor: 'pointer', height: 'var(--bar-h)', boxSizing: 'border-box', padding: '0 var(--control-px)', marginBottom: '-1px', borderBottom: t.label === active ? '2px solid var(--action-primary)' : '2px solid transparent', display: 'inline-flex', alignItems: 'center', gap: '6px', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: t.label === active ? 'var(--action-primary)' : 'var(--ink, var(--text-body))', whiteSpace: 'nowrap' }\">{{ t.label }}<CountBadge :count=\"t.count\" :selected=\"t.label === active\" :show-zero=\"t.showZero ?? showZero\" /></button>\n </div>\n</template>\n","tabs/ViewToggle.jsx":"import React from \"react\";\nimport { IconButton } from \"../buttons/IconButton.jsx\";\n\n/** Two-state list/grid icon toggle (palette header). Two IconButtons at the region's tier; omit `size` to inherit. */\nexport function ViewToggle({ value = \"grid\", onChange, size, style }) {\n return (\n <div data-size={size} style={{ display: \"inline-flex\", gap: 2, ...style }}>\n <IconButton icon=\"list\" active={value === \"list\"} onClick={() => onChange && onChange(\"list\")} label=\"List view\" />\n <IconButton icon=\"layout-grid\" active={value === \"grid\"} onClick={() => onChange && onChange(\"grid\")} label=\"Grid view\" />\n </div>\n );\n}\n","tabs/ViewToggle.vue":"<script setup>\nimport IconButton from '../buttons/IconButton.vue'\n// Two-state list/grid icon toggle (palette header). Two IconButtons at the region's tier; omit `size` to inherit.\ndefineProps({ modelValue: { type: String, default: 'grid' }, size: String, style: Object })\nconst emit = defineEmits(['update:modelValue'])\n</script>\n<template>\n <div :data-size=\"size\" :style=\"{ display: 'inline-flex', gap: '2px', ...style }\">\n <IconButton icon=\"list\" :active=\"modelValue === 'list'\" label=\"List view\" @click=\"emit('update:modelValue', 'list')\" />\n <IconButton icon=\"layout-grid\" :active=\"modelValue === 'grid'\" label=\"Grid view\" @click=\"emit('update:modelValue', 'grid')\" />\n </div>\n</template>\n","tabs/PanelTabs.vue":"<script setup>\nimport { computed } from 'vue'\nimport CountBadge from './CountBadge.vue'\n// Panel tabs (Node Info · Calc Rules · …): a lighter underline tab bar at the region's bar height with regular-weight control text. Put the panel in an sm region for the compact 32px/12px look.\n// tabs: string[] | { label, count?, showZero? }[] — a count renders as a CountBadge 6px right of the label; active is matched by label.\nconst props = defineProps({ tabs: { type: Array, default: () => [] }, active: String, size: String, showZero: Boolean, style: Object })\nconst emit = defineEmits(['change'])\nconst items = computed(() => props.tabs.map(t => typeof t === 'string' ? { label: t } : t))\n</script>\n<template>\n <div role=\"tablist\" :data-size=\"size\" :style=\"{ display: 'flex', borderBottom: '1px solid var(--border-subtle)', ...style }\">\n <button v-for=\"t in items\" :key=\"t.label\" type=\"button\" role=\"tab\" :aria-selected=\"t.label === active\" :data-ink=\"t.label === active ? undefined : ''\" @click=\"emit('change', t.label)\"\n :style=\"{ background: 'transparent', border: 'none', cursor: 'pointer', height: 'var(--bar-h)', boxSizing: 'border-box', padding: '0 var(--control-px)', marginBottom: '-1px', borderBottom: t.label === active ? '2px solid var(--action-primary)' : '2px solid transparent', display: 'inline-flex', alignItems: 'center', gap: '6px', fontFamily: 'var(--font-sans)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: t.label === active ? 'var(--action-primary)' : 'var(--ink, var(--text-secondary))', whiteSpace: 'nowrap' }\">{{ t.label }}<CountBadge :count=\"t.count\" :selected=\"t.label === active\" :show-zero=\"t.showZero ?? showZero\" /></button>\n </div>\n</template>\n","tabs/PillTabs.vue":"<script setup>\nimport { computed } from 'vue'\nimport CountBadge from './CountBadge.vue'\n// Text pill filter tabs. Active = tinted pill. Pills are control-height (sm 28 · md 32 · lg 40); omit `size` to inherit.\n// tabs: string[] | { label, count?, showZero? }[] — a count draws a CountBadge 6px right of the label; active is matched by label.\nconst props = defineProps({ tabs: { type: Array, default: () => [] }, active: String, size: String, showZero: Boolean, style: Object })\nconst emit = defineEmits(['change'])\nconst items = computed(() => props.tabs.map(t => typeof t === 'string' ? { label: t } : t))\n</script>\n<template>\n <div role=\"tablist\" :data-size=\"size\" :style=\"{ display: 'flex', gap: 'var(--control-gap)', ...style }\">\n <button v-for=\"t in items\" :key=\"t.label\" type=\"button\" role=\"tab\" :aria-selected=\"t.label === active\" :data-ink=\"t.label === active ? undefined : ''\" :data-wash=\"t.label === active ? undefined : ''\" @click=\"emit('change', t.label)\"\n :style=\"{ background: t.label === active ? 'var(--bg-active)' : 'var(--wash, transparent)', border: 'none', cursor: 'pointer', height: 'var(--control-h)', padding: '0 var(--control-px)', borderRadius: 'var(--radius-md)', display: 'inline-flex', alignItems: 'center', gap: '6px', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: t.label === active ? 'var(--text-heading)' : 'var(--ink, var(--text-secondary))', whiteSpace: 'nowrap' }\">{{ t.label }}<CountBadge :count=\"t.count\" :selected=\"t.label === active\" :show-zero=\"t.showZero ?? showZero\" /></button>\n </div>\n</template>\n","tabs/CountBadge.vue":"<script setup>\nimport { computed } from 'vue'\n// Count badge beside a segment / pill label: --count-h tall (sm 16 · md and lg 18), 6px sides, full radius, 12px tabular figures\n// (digits are Latin, so not bumped in CJK). Fill: the alpha wash --neutral-alpha-8, so it darkens any surface by the same step (white tab,\n// #f5f5f5 active pill, dark theme); text tells selected from unselected: --text-heading vs --text-body (a lighter grey fails 4.5:1 at 12px).\n// Hidden for 0 or a missing count unless showZero, which draws a muted 0.\nconst props = defineProps({ count: Number, selected: Boolean, showZero: Boolean, style: Object })\nconst zero = computed(() => props.count === 0 || props.count == null)\n</script>\n<template>\n <span v-if=\"!zero || showZero\" aria-hidden=\"true\" :style=\"{ display: 'inline-flex', alignItems: 'center', height: 'var(--count-h)', padding: '0 6px', borderRadius: 'var(--radius-full)', background: 'var(--neutral-alpha-8)', color: zero ? 'var(--text-muted)' : selected ? 'var(--text-heading)' : 'var(--text-body)', fontFamily: 'var(--font-sans)', fontSize: '12px', lineHeight: 'var(--count-h)', fontWeight: 'var(--weight-medium)', letterSpacing: 0, fontVariantNumeric: 'tabular-nums', flexShrink: 0, ...style }\">{{ zero ? 0 : count }}</span>\n</template>\n"});