@tcn/ui 0.0.4 → 0.1.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/dist/actions/button/base_button/base_button.d.ts.map +1 -1
- package/dist/actions/button/base_button/base_button.js +17 -12
- package/dist/actions/button/base_button/base_button.js.map +1 -1
- package/dist/actions/button/button/button.d.ts.map +1 -1
- package/dist/actions/button/button/button.js +7 -7
- package/dist/actions/button/button/button.js.map +1 -1
- package/dist/actions/button/slim_button/slim_button.js +2 -2
- package/dist/actions/button/slim_button/slim_button.js.map +1 -1
- package/dist/button.css +1 -1
- package/dist/footer.css +1 -1
- package/dist/form/field/common/field_error.js +3 -2
- package/dist/form/field/common/field_error.js.map +1 -1
- package/dist/inputs/input/input.d.ts +2 -2
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/input/input.js.map +1 -1
- package/dist/inputs/options/option.d.ts +1 -0
- package/dist/inputs/options/option.d.ts.map +1 -1
- package/dist/inputs/options/option.js.map +1 -1
- package/dist/inputs/phone_number_input/phone_number_input.d.ts +6 -1
- package/dist/inputs/phone_number_input/phone_number_input.d.ts.map +1 -1
- package/dist/inputs/phone_number_input/phone_number_input.js +169 -125
- package/dist/inputs/phone_number_input/phone_number_input.js.map +1 -1
- package/dist/inputs/suggestions/suggestion_item.d.ts +1 -1
- package/dist/inputs/suggestions/suggestion_item.d.ts.map +1 -1
- package/dist/inputs/suggestions/suggestion_item.js +23 -18
- package/dist/inputs/suggestions/suggestion_item.js.map +1 -1
- package/dist/inputs/suggestions/suggestion_list.d.ts +1 -1
- package/dist/inputs/suggestions/suggestion_list.d.ts.map +1 -1
- package/dist/inputs/suggestions/suggestion_list.js +105 -95
- package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
- package/dist/layouts/footer/footer.js +5 -5
- package/dist/layouts/footer/footer.js.map +1 -1
- package/dist/layouts/index.d.ts +3 -2
- package/dist/layouts/index.d.ts.map +1 -1
- package/dist/layouts/index.js +26 -24
- package/dist/layouts/index.js.map +1 -1
- package/dist/layouts/list/item.d.ts +1 -0
- package/dist/layouts/list/item.d.ts.map +1 -1
- package/dist/layouts/list/item.js +17 -6
- package/dist/layouts/list/item.js.map +1 -1
- package/dist/layouts/list/list.js +10 -10
- package/dist/layouts/list/list.js.map +1 -1
- package/dist/overlay/context_menu/context_menu.js +4 -4
- package/dist/overlay/index.js +3 -3
- package/dist/overlay/popper/popper.js +12 -12
- package/dist/{portal-qqIp4SIl.js → overlay/portal/portal.js} +3 -3
- package/dist/overlay/portal/portal.js.map +1 -0
- package/dist/overlay/portal/portal_platform.js +3 -4
- package/dist/overlay/portal/portal_platform.js.map +1 -1
- package/dist/phone_number_input.css +1 -1
- package/dist/slim_button.css +1 -1
- package/dist/surfaces/card/card.d.ts.map +1 -1
- package/dist/surfaces/card/card.js +7 -16
- package/dist/surfaces/card/card.js.map +1 -1
- package/dist/surfaces/confirm/confirm.js +4 -4
- package/dist/themes/index.js +6 -141
- package/dist/themes/index.js.map +1 -1
- package/dist/themes/stylesheets/reset.js +140 -0
- package/dist/themes/stylesheets/reset.js.map +1 -0
- package/dist/themes/themes/ergo/ergo_theme.js +595 -0
- package/dist/themes/themes/ergo/ergo_theme.js.map +1 -0
- package/dist/tokens/bubble/bubble.js +17 -16
- package/dist/tokens/bubble/bubble.js.map +1 -1
- package/dist/tokens/chip/chip.js +9 -8
- package/dist/tokens/chip/chip.js.map +1 -1
- package/dist/typography/title/title.js +8 -8
- package/dist/typography/title/title.js.map +1 -1
- package/package.json +3 -3
- package/src/actions/button/base_button/base_button.tsx +7 -2
- package/src/actions/button/button/button.module.css +0 -78
- package/src/actions/button/button/button.tsx +2 -4
- package/src/actions/button/slim_button/slim_button.module.css +0 -26
- package/src/actions/button/slim_button/slim_button.tsx +1 -1
- package/src/inputs/input/input.tsx +3 -2
- package/src/inputs/options/option.tsx +1 -0
- package/src/inputs/phone_number_input/phone_number_input.module.css +12 -0
- package/src/inputs/phone_number_input/phone_number_input.stories.tsx +8 -0
- package/src/inputs/phone_number_input/phone_number_input.tsx +99 -21
- package/src/inputs/suggestions/suggestion_item.tsx +12 -2
- package/src/inputs/suggestions/suggestion_list.tsx +22 -3
- package/src/layouts/footer/footer.module.css +0 -1
- package/src/layouts/footer/footer.tsx +1 -1
- package/src/layouts/index.ts +3 -2
- package/src/layouts/list/item.tsx +10 -2
- package/src/layouts/list/list.tsx +2 -2
- package/src/surfaces/card/card.tsx +2 -8
- package/src/surfaces/modal/__stories__/modal.stories.tsx +1 -1
- package/src/surfaces/panel/__stories__/panel.stories.tsx +13 -12
- package/src/themes/themes/ergo/__stories__/components/material_picker/sb_inverted_materials.module.css +34 -0
- package/src/themes/themes/ergo/__stories__/components/material_picker/sb_material_picker.tsx +52 -0
- package/src/themes/themes/ergo/__stories__/components/tone_picker/sb_card.module.css +5 -0
- package/src/themes/themes/ergo/__stories__/components/tone_picker/sb_tone_card.tsx +40 -0
- package/src/themes/themes/ergo/__stories__/components/tone_picker/sb_tone_picker.tsx +83 -0
- package/src/themes/themes/ergo/__stories__/components/tone_picker/types.ts +7 -0
- package/src/themes/themes/ergo/__stories__/material.stories.tsx +154 -0
- package/src/themes/themes/ergo/__stories__/sb_materials.module.css +110 -0
- package/src/themes/themes/ergo/__stories__/utils.ts +92 -0
- package/src/themes/themes/ergo/ergo_theme.css +298 -35
- package/src/typography/title/title.tsx +1 -1
- package/tsconfig.json +0 -3
- package/dist/card.css +0 -1
- package/dist/portal-qqIp4SIl.js.map +0 -1
- package/dist/themes/stylesheets/reset.css +0 -1
- package/dist/themes/themes/ergo/ergo_theme.css +0 -1
- package/dist/themes/themes/windows_98/windows_98.css +0 -1
- package/src/surfaces/card/card.module.css +0 -5
- /package/dist/{overlay/portal/portal.css → portal_platform.css} +0 -0
package/dist/tokens/chip/chip.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { HStack as
|
|
1
|
+
import { jsx as m } from "react/jsx-runtime";
|
|
2
|
+
import { HStack as n } from "../../stacks/h_stack.js";
|
|
3
3
|
import { clsx as f } from "clsx";
|
|
4
4
|
import h from "react";
|
|
5
5
|
import { theme as s } from "../../themes/theme_variables.js";
|
|
6
|
-
import
|
|
7
|
-
|
|
6
|
+
import "../../themes/stylesheets/reset.js";
|
|
7
|
+
import '../../chip.css';const l = "_chip_35f6f0b", a = { chip: l }, R = h.forwardRef(function({ children: t, style: o, className: i, color: r = s.accentColor, ...c }, e) {
|
|
8
|
+
const p = {
|
|
8
9
|
"--chip-color": r,
|
|
9
10
|
...o
|
|
10
11
|
};
|
|
11
|
-
return /* @__PURE__ */
|
|
12
|
-
|
|
12
|
+
return /* @__PURE__ */ m(
|
|
13
|
+
n,
|
|
13
14
|
{
|
|
14
15
|
ref: e,
|
|
15
16
|
inline: !0,
|
|
@@ -17,13 +18,13 @@ import '../../chip.css';const l = "_chip_35f6f0b", a = { chip: l }, w = h.forwar
|
|
|
17
18
|
height: "auto",
|
|
18
19
|
vAlign: "center",
|
|
19
20
|
className: f(a.chip, "chip", i),
|
|
20
|
-
style:
|
|
21
|
+
style: p,
|
|
21
22
|
...c,
|
|
22
23
|
children: t
|
|
23
24
|
}
|
|
24
25
|
);
|
|
25
26
|
});
|
|
26
27
|
export {
|
|
27
|
-
|
|
28
|
+
R as Chip
|
|
28
29
|
};
|
|
29
30
|
//# sourceMappingURL=chip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chip.js","sources":["../../../src/tokens/chip/chip.tsx"],"sourcesContent":["import { HStack, HStackProps } from '../../stacks/h_stack.js';\nimport { clsx } from 'clsx';\nimport React from 'react';\nimport styles from './chip.module.css';\nimport { theme } from '../../themes/index.js';\n\nexport interface ChipProps extends HStackProps {\n children?: React.ReactNode;\n color?: string;\n disabled?: boolean;\n}\n\nexport const Chip = React.forwardRef(function Chip(\n { children, style, className, color = theme.accentColor, ...props }: ChipProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const finalStyle = {\n '--chip-color': color,\n ...style,\n };\n\n return (\n <HStack\n ref={ref}\n inline\n width=\"auto\"\n height=\"auto\"\n vAlign=\"center\"\n className={clsx(styles.chip, 'chip', className)}\n style={finalStyle}\n {...props}\n >\n {children}\n </HStack>\n );\n});\n"],"names":["Chip","React","children","style","className","color","theme","props","ref","finalStyle","jsx","HStack","clsx","styles"],"mappings":"
|
|
1
|
+
{"version":3,"file":"chip.js","sources":["../../../src/tokens/chip/chip.tsx"],"sourcesContent":["import { HStack, HStackProps } from '../../stacks/h_stack.js';\nimport { clsx } from 'clsx';\nimport React from 'react';\nimport styles from './chip.module.css';\nimport { theme } from '../../themes/index.js';\n\nexport interface ChipProps extends HStackProps {\n children?: React.ReactNode;\n color?: string;\n disabled?: boolean;\n}\n\nexport const Chip = React.forwardRef(function Chip(\n { children, style, className, color = theme.accentColor, ...props }: ChipProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const finalStyle = {\n '--chip-color': color,\n ...style,\n };\n\n return (\n <HStack\n ref={ref}\n inline\n width=\"auto\"\n height=\"auto\"\n vAlign=\"center\"\n className={clsx(styles.chip, 'chip', className)}\n style={finalStyle}\n {...props}\n >\n {children}\n </HStack>\n );\n});\n"],"names":["Chip","React","children","style","className","color","theme","props","ref","finalStyle","jsx","HStack","clsx","styles"],"mappings":";;;;;;4CAYaA,IAAOC,EAAM,WAAW,SACnC,EAAE,UAAAC,GAAU,OAAAC,GAAO,WAAAC,GAAW,OAAAC,IAAQC,EAAM,aAAa,GAAGC,EAAA,GAC5DC,GACA;AACA,QAAMC,IAAa;AAAA,IACjB,gBAAgBJ;AAAA,IAChB,GAAGF;AAAA,EAAA;AAGL,SACE,gBAAAO;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAH;AAAA,MACA,QAAM;AAAA,MACN,OAAM;AAAA,MACN,QAAO;AAAA,MACP,QAAO;AAAA,MACP,WAAWI,EAAKC,EAAO,MAAM,QAAQT,CAAS;AAAA,MAC9C,OAAOK;AAAA,MACN,GAAGF;AAAA,MAEH,UAAAL;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;"}
|
|
@@ -4,30 +4,30 @@ import { s as x } from "../../title.module-B16de2jd.js";
|
|
|
4
4
|
function A({
|
|
5
5
|
size: a = "md",
|
|
6
6
|
emphasis: o = "normal",
|
|
7
|
-
hierarchy:
|
|
7
|
+
hierarchy: p = "primary",
|
|
8
8
|
color: n,
|
|
9
|
-
children:
|
|
10
|
-
className:
|
|
9
|
+
children: c,
|
|
10
|
+
className: g,
|
|
11
11
|
style: i = {},
|
|
12
12
|
padStart: r,
|
|
13
13
|
padEnd: e,
|
|
14
14
|
padBottom: f,
|
|
15
15
|
padTop: l,
|
|
16
16
|
pad: m,
|
|
17
|
-
selectable:
|
|
17
|
+
selectable: h = !0,
|
|
18
18
|
as: d
|
|
19
19
|
}) {
|
|
20
20
|
let t = d;
|
|
21
21
|
return d == null && (a === "lg" ? t = "h1" : a === "md" ? t = "h2" : t = "h3"), m && (i.padding = m), r && (i.paddingInlineStart = r), e && (i.paddingInlineEnd = e), l && (i.paddingTop = l), f && (i.paddingBottom = f), n && (i.color = n), /* @__PURE__ */ s(
|
|
22
22
|
t,
|
|
23
23
|
{
|
|
24
|
-
"data-hierarchy":
|
|
24
|
+
"data-hierarchy": p,
|
|
25
25
|
"data-emphasis": o,
|
|
26
|
-
"data-selectable":
|
|
27
|
-
className: u(x.title, "title", "tcn-title",
|
|
26
|
+
"data-selectable": h,
|
|
27
|
+
className: u(x.title, "title", "tcn-typography", "tcn-title", g),
|
|
28
28
|
style: i,
|
|
29
29
|
"data-size": a,
|
|
30
|
-
children:
|
|
30
|
+
children: c
|
|
31
31
|
}
|
|
32
32
|
);
|
|
33
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"title.js","sources":["../../../src/typography/title/title.tsx"],"sourcesContent":["import React from 'react';\nimport { clsx } from 'clsx';\nimport type { WithDetailedHTMLProps } from '../../stacks/types/as.js';\nimport type { Emphasis, Hierarchy, Size } from '../../utils/index.js';\nimport styles from './title.module.css';\n\nexport interface TitleOwnProps {\n children?: string;\n size?: Size;\n emphasis?: Emphasis;\n hierarchy?: Hierarchy;\n color?: string;\n pad?: string;\n padStart?: string;\n padEnd?: string;\n padTop?: string;\n padBottom?: string;\n selectable?: boolean;\n as?: string;\n}\n\nexport type TitleProps = WithDetailedHTMLProps<TitleOwnProps, 'h1' | 'h2' | 'h3'>;\n\nexport function Title({\n size = 'md',\n emphasis = 'normal',\n hierarchy = 'primary',\n color,\n children,\n className,\n style = {},\n padStart,\n padEnd,\n padBottom,\n padTop,\n pad,\n selectable = true,\n as,\n}: TitleProps) {\n let As: React.ElementType = as as React.ElementType;\n\n if (as == null) {\n if (size === 'lg') {\n As = 'h1';\n } else if (size === 'md') {\n As = 'h2';\n } else {\n As = 'h3';\n }\n }\n\n if (pad) {\n style.padding = pad;\n }\n\n if (padStart) {\n style.paddingInlineStart = padStart;\n }\n\n if (padEnd) {\n style.paddingInlineEnd = padEnd;\n }\n\n if (padTop) {\n style.paddingTop = padTop;\n }\n\n if (padBottom) {\n style.paddingBottom = padBottom;\n }\n\n if (color) {\n style.color = color;\n }\n\n return (\n <As\n data-hierarchy={hierarchy}\n data-emphasis={emphasis}\n data-selectable={selectable}\n className={clsx(styles['title'], 'title', 'tcn-title', className)}\n style={style}\n data-size={size}\n >\n {children}\n </As>\n );\n}\n"],"names":["Title","size","emphasis","hierarchy","color","children","className","style","padStart","padEnd","padBottom","padTop","pad","selectable","as","As","jsx","clsx","styles"],"mappings":";;;AAuBO,SAASA,EAAM;AAAA,EACpB,MAAAC,IAAO;AAAA,EACP,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC,IAAQ,CAAA;AAAA,EACR,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,QAAAC;AAAA,EACA,KAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,IAAAC;AACF,GAAe;AACb,MAAIC,IAAwBD;AAE5B,SAAIA,KAAM,SACJb,MAAS,OACXc,IAAK,OACId,MAAS,OAClBc,IAAK,OAELA,IAAK,OAILH,MACFL,EAAM,UAAUK,IAGdJ,MACFD,EAAM,qBAAqBC,IAGzBC,MACFF,EAAM,mBAAmBE,IAGvBE,MACFJ,EAAM,aAAaI,IAGjBD,MACFH,EAAM,gBAAgBG,IAGpBN,MACFG,EAAM,QAAQH,IAId,gBAAAY;AAAA,IAACD;AAAA,IAAA;AAAA,MACC,kBAAgBZ;AAAA,MAChB,iBAAeD;AAAA,MACf,mBAAiBW;AAAA,MACjB,WAAWI,EAAKC,EAAO,OAAU,SAAS,aAAaZ,CAAS;AAAA,
|
|
1
|
+
{"version":3,"file":"title.js","sources":["../../../src/typography/title/title.tsx"],"sourcesContent":["import React from 'react';\nimport { clsx } from 'clsx';\nimport type { WithDetailedHTMLProps } from '../../stacks/types/as.js';\nimport type { Emphasis, Hierarchy, Size } from '../../utils/index.js';\nimport styles from './title.module.css';\n\nexport interface TitleOwnProps {\n children?: string;\n size?: Size;\n emphasis?: Emphasis;\n hierarchy?: Hierarchy;\n color?: string;\n pad?: string;\n padStart?: string;\n padEnd?: string;\n padTop?: string;\n padBottom?: string;\n selectable?: boolean;\n as?: string;\n}\n\nexport type TitleProps = WithDetailedHTMLProps<TitleOwnProps, 'h1' | 'h2' | 'h3'>;\n\nexport function Title({\n size = 'md',\n emphasis = 'normal',\n hierarchy = 'primary',\n color,\n children,\n className,\n style = {},\n padStart,\n padEnd,\n padBottom,\n padTop,\n pad,\n selectable = true,\n as,\n}: TitleProps) {\n let As: React.ElementType = as as React.ElementType;\n\n if (as == null) {\n if (size === 'lg') {\n As = 'h1';\n } else if (size === 'md') {\n As = 'h2';\n } else {\n As = 'h3';\n }\n }\n\n if (pad) {\n style.padding = pad;\n }\n\n if (padStart) {\n style.paddingInlineStart = padStart;\n }\n\n if (padEnd) {\n style.paddingInlineEnd = padEnd;\n }\n\n if (padTop) {\n style.paddingTop = padTop;\n }\n\n if (padBottom) {\n style.paddingBottom = padBottom;\n }\n\n if (color) {\n style.color = color;\n }\n\n return (\n <As\n data-hierarchy={hierarchy}\n data-emphasis={emphasis}\n data-selectable={selectable}\n className={clsx(styles['title'], 'title', 'tcn-typography', 'tcn-title', className)}\n style={style}\n data-size={size}\n >\n {children}\n </As>\n );\n}\n"],"names":["Title","size","emphasis","hierarchy","color","children","className","style","padStart","padEnd","padBottom","padTop","pad","selectable","as","As","jsx","clsx","styles"],"mappings":";;;AAuBO,SAASA,EAAM;AAAA,EACpB,MAAAC,IAAO;AAAA,EACP,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC,IAAQ,CAAA;AAAA,EACR,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,QAAAC;AAAA,EACA,KAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,IAAAC;AACF,GAAe;AACb,MAAIC,IAAwBD;AAE5B,SAAIA,KAAM,SACJb,MAAS,OACXc,IAAK,OACId,MAAS,OAClBc,IAAK,OAELA,IAAK,OAILH,MACFL,EAAM,UAAUK,IAGdJ,MACFD,EAAM,qBAAqBC,IAGzBC,MACFF,EAAM,mBAAmBE,IAGvBE,MACFJ,EAAM,aAAaI,IAGjBD,MACFH,EAAM,gBAAgBG,IAGpBN,MACFG,EAAM,QAAQH,IAId,gBAAAY;AAAA,IAACD;AAAA,IAAA;AAAA,MACC,kBAAgBZ;AAAA,MAChB,iBAAeD;AAAA,MACf,mBAAiBW;AAAA,MACjB,WAAWI,EAAKC,EAAO,OAAU,SAAS,kBAAkB,aAAaZ,CAAS;AAAA,MAClF,OAAAC;AAAA,MACA,aAAWN;AAAA,MAEV,UAAAI;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tcn/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "TCN",
|
|
@@ -128,8 +128,8 @@
|
|
|
128
128
|
"dependencies": {
|
|
129
129
|
"clsx": "^2.1.1",
|
|
130
130
|
"react-color": "^2.19.3",
|
|
131
|
-
"@tcn/
|
|
132
|
-
"@tcn/
|
|
131
|
+
"@tcn/icons": "2.1.1",
|
|
132
|
+
"@tcn/state": "1.0.1"
|
|
133
133
|
},
|
|
134
134
|
"scripts": {
|
|
135
135
|
"build": "vite build",
|
|
@@ -27,7 +27,7 @@ export const BaseButton = React.forwardRef<HTMLButtonElement, BaseButtonProps>(
|
|
|
27
27
|
style,
|
|
28
28
|
color,
|
|
29
29
|
hierarchy = 'secondary',
|
|
30
|
-
size = '
|
|
30
|
+
size = 'md',
|
|
31
31
|
onTouchStart,
|
|
32
32
|
onContextMenu,
|
|
33
33
|
...props
|
|
@@ -68,7 +68,12 @@ export const BaseButton = React.forwardRef<HTMLButtonElement, BaseButtonProps>(
|
|
|
68
68
|
data-hierarchy={hierarchy}
|
|
69
69
|
data-size={size}
|
|
70
70
|
data-is-disabled={Boolean(props.disabled)}
|
|
71
|
-
className={clsx(
|
|
71
|
+
className={clsx(
|
|
72
|
+
styles['base-button'],
|
|
73
|
+
'tcn-interactive',
|
|
74
|
+
'tcn-base-button',
|
|
75
|
+
className
|
|
76
|
+
)}
|
|
72
77
|
style={finalStyle}
|
|
73
78
|
onTouchStart={handleTouchStart}
|
|
74
79
|
onContextMenu={handleContextMenu}
|
|
@@ -6,90 +6,12 @@
|
|
|
6
6
|
--button-color-disabled: var(--status-disabled, #cccccc);
|
|
7
7
|
|
|
8
8
|
min-height: var(--button-height);
|
|
9
|
-
padding: 4px 8px;
|
|
10
|
-
border-radius: 4px;
|
|
11
9
|
width: auto;
|
|
12
|
-
border: 1px solid transparent;
|
|
13
|
-
outline: none;
|
|
14
10
|
cursor: pointer;
|
|
15
|
-
background: transparent;
|
|
16
11
|
font-size: calc(14px * var(--scalar, 1));
|
|
17
12
|
line-height: calc(16px * var(--scalar, 1));
|
|
18
13
|
}
|
|
19
14
|
|
|
20
|
-
.button:focus-visible {
|
|
21
|
-
outline: 3px solid color-mix(in srgb, var(--button-color) 40%, transparent);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/* Primary */
|
|
25
|
-
.button[data-hierarchy="primary"] {
|
|
26
|
-
background: var(--button-color);
|
|
27
|
-
color: #ffffff;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.button[data-hierarchy="primary"]:hover {
|
|
31
|
-
background: var(--button-color-hover);
|
|
32
|
-
color: #ffffff;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.button[data-hierarchy="primary"]:active {
|
|
36
|
-
background: var(--button-color-active);
|
|
37
|
-
box-shadow: none;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/* Secondary */
|
|
41
|
-
.button[data-hierarchy="secondary"] {
|
|
42
|
-
color: rgb(57, 85, 120);
|
|
43
|
-
border-color: rgb(57, 85, 120);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.button[data-hierarchy="secondary"]:hover {
|
|
47
|
-
background: color-mix(in srgb, rgb(57, 85, 120) 10%, rgb(255, 255, 255, 0.5));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.button[data-hierarchy="secondary"]:active {
|
|
51
|
-
background: color-mix(in srgb, rgb(57, 85, 120) 25%, rgb(255, 255, 255, 0.5));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/* Tertiary */
|
|
55
|
-
.button[data-hierarchy="tertiary"] {
|
|
56
|
-
border-color: transparent;
|
|
57
|
-
color: rgb(57, 85, 120);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.button[data-hierarchy="tertiary"]:hover {
|
|
61
|
-
text-decoration: underline;
|
|
62
|
-
text-decoration-color: rgb(57, 85, 120);
|
|
63
|
-
text-decoration-thickness: 1px;
|
|
64
|
-
text-underline-offset: 2px;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.button[data-hierarchy="tertiary"]:active {
|
|
68
|
-
opacity: 0.5;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/* Disabled */
|
|
72
|
-
.button[data-is-disabled="true"] {
|
|
73
|
-
pointer-events: none;
|
|
74
|
-
background: var(--button-color-disabled);
|
|
75
|
-
color: #ffffff;
|
|
76
|
-
border-color: var(--button-color-disabled);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/* Disabled Secondary */
|
|
80
|
-
.button[data-hierarchy="secondary"][data-is-disabled="true"] {
|
|
81
|
-
background: transparent;
|
|
82
|
-
color: var(--button-color-disabled);
|
|
83
|
-
border-color: var(--button-color-disabled);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/* Disabled Tertiary */
|
|
87
|
-
.button[data-hierarchy="tertiary"][data-is-disabled="true"] {
|
|
88
|
-
background: transparent;
|
|
89
|
-
color: var(--button-color-disabled);
|
|
90
|
-
border-color: transparent;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
15
|
/* Sizes */
|
|
94
16
|
.button[data-size="sm"] {
|
|
95
17
|
--button-height: calc(22px * var(--scalar, 1));
|
|
@@ -12,13 +12,11 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function
|
|
|
12
12
|
return (
|
|
13
13
|
<BaseButton
|
|
14
14
|
ref={ref}
|
|
15
|
-
className={clsx(styles.button, '
|
|
15
|
+
className={clsx(styles.button, 'tcn-button', className)}
|
|
16
16
|
{...props}
|
|
17
17
|
>
|
|
18
18
|
{typeof children === 'string' ? (
|
|
19
|
-
<span className={clsx(styles['button-text'], '
|
|
20
|
-
{children}
|
|
21
|
-
</span>
|
|
19
|
+
<span className={clsx(styles['button-text'], 'tcn-button-text')}>{children}</span>
|
|
22
20
|
) : (
|
|
23
21
|
children
|
|
24
22
|
)}
|
|
@@ -5,29 +5,3 @@
|
|
|
5
5
|
.slim-button[data-is-disabled="true"] {
|
|
6
6
|
pointer-events: none;
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
.slim-button[data-size="sm"] {
|
|
10
|
-
padding: 1px;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.slim-button[data-size="md"] {
|
|
14
|
-
padding: 2px;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.slim-button[data-size="lg"] {
|
|
18
|
-
padding: 3px;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.slim-button[data-hierarchy="tertiary"][data-is-disabled="true"] {
|
|
22
|
-
background-color: transparent;
|
|
23
|
-
border: none;
|
|
24
|
-
color: var(--button-color-disabled);
|
|
25
|
-
min-height: auto;
|
|
26
|
-
pointer-events: none;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.slim-button[data-hierarchy="secondary"][data-is-disabled="true"] {
|
|
30
|
-
background-color: transparent;
|
|
31
|
-
border: 1px solid var(--button-color-disabled);
|
|
32
|
-
color: var(--button-color-disabled);
|
|
33
|
-
}
|
|
@@ -9,7 +9,7 @@ export const SlimButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
9
9
|
return (
|
|
10
10
|
<Button
|
|
11
11
|
ref={ref}
|
|
12
|
-
className={clsx(styles['slim-button'], 'slim-button', className)}
|
|
12
|
+
className={clsx(styles['slim-button'], 'tcn-slim-button', className)}
|
|
13
13
|
{...props}
|
|
14
14
|
>
|
|
15
15
|
{children}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { InputHTMLAttributes } from 'react';
|
|
4
4
|
import styles from './input.module.css';
|
|
5
5
|
|
|
6
|
-
export interface InputProps
|
|
6
|
+
export interface InputProps
|
|
7
|
+
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
|
|
7
8
|
type?: React.HTMLInputTypeAttribute;
|
|
8
9
|
width?: string;
|
|
9
10
|
height?: string;
|
|
@@ -48,3 +48,15 @@
|
|
|
48
48
|
max-height: calc(26px * var(--scalar, 1)) !important;
|
|
49
49
|
max-width: calc(26px * var(--scalar, 1)) !important;
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
.phone-number-input-obfuscated {
|
|
53
|
+
user-select: none;
|
|
54
|
+
-webkit-user-select: none;
|
|
55
|
+
cursor: default;
|
|
56
|
+
width: 100%;
|
|
57
|
+
height: 100%;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.phone-number-input-obfuscated::selection {
|
|
61
|
+
background: transparent;
|
|
62
|
+
}
|
|
@@ -90,6 +90,14 @@ export function PhoneNumberInput() {
|
|
|
90
90
|
>
|
|
91
91
|
Bob Johnson - +1 (435) 586-5955
|
|
92
92
|
</Option>
|
|
93
|
+
<Option
|
|
94
|
+
value="+14355865956"
|
|
95
|
+
label="Obfuscated Number"
|
|
96
|
+
keywords={['obfuscated', 'number']}
|
|
97
|
+
obfuscate={true}
|
|
98
|
+
>
|
|
99
|
+
Obfuscated Number
|
|
100
|
+
</Option>
|
|
93
101
|
</Base>
|
|
94
102
|
</td>
|
|
95
103
|
</tr>
|
|
@@ -21,6 +21,16 @@ import { NotebookIcon } from '@tcn/icons/notebook_icon.js';
|
|
|
21
21
|
import { Option, OptionProps } from '../options/option.js';
|
|
22
22
|
import { SuggestionList } from '../suggestions/suggestion_list.js';
|
|
23
23
|
import { stripNonNumericAfterCountryCode } from './utils.js';
|
|
24
|
+
import { useForkRef } from '../../utils/index.js';
|
|
25
|
+
|
|
26
|
+
const OBFUSCATED_CHARACTER = '•';
|
|
27
|
+
|
|
28
|
+
function createObfuscatedMasks(masks: { mask: string; placeholder?: string }[]) {
|
|
29
|
+
return masks.map(m => ({
|
|
30
|
+
...m,
|
|
31
|
+
placeholder: m.mask.replace(/[9a*]/g, OBFUSCATED_CHARACTER),
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
24
34
|
|
|
25
35
|
const countryList = countriesPhoneInformation.map(i => ({
|
|
26
36
|
name: i.name,
|
|
@@ -109,7 +119,12 @@ export interface PhoneNumberInputProps
|
|
|
109
119
|
extends Omit<HStackProps, 'onChange' | 'children'> {
|
|
110
120
|
value?: string;
|
|
111
121
|
defaultCountry?: string;
|
|
112
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Callback fired when the phone number value changes.
|
|
124
|
+
* @param value - The phone number value with country prefix
|
|
125
|
+
* @param obfuscate - Whether the selected phone number is obfuscated (e.g., from a phone book entry marked as obfuscated)
|
|
126
|
+
*/
|
|
127
|
+
onChange?: (value: string, obfuscate: boolean) => void;
|
|
113
128
|
countrySelectRef?: React.Ref<HTMLButtonElement>;
|
|
114
129
|
phoneNumberInputRef?: React.Ref<HTMLInputElement>;
|
|
115
130
|
disabled?: boolean;
|
|
@@ -161,6 +176,10 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
161
176
|
const [currentMasks, setCurrentMasks] = useState([
|
|
162
177
|
...countriesPhoneInformation[0].masks,
|
|
163
178
|
]);
|
|
179
|
+
const [obfuscateValue, setObfuscateValue] = useState(false);
|
|
180
|
+
const [shouldFocusAfterClear, setShouldFocusAfterClear] = useState(false);
|
|
181
|
+
const internalInputRef = useRef<HTMLInputElement>(null);
|
|
182
|
+
const forkedInputRef = useForkRef(numberRef, internalInputRef);
|
|
164
183
|
|
|
165
184
|
const countryOptions = useMemo(() => {
|
|
166
185
|
return createCountryOptions(allowedCountryCodes);
|
|
@@ -183,7 +202,7 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
183
202
|
|
|
184
203
|
const value = `${countryInformation.prefix}${stripNonNumericAfterCountryCode(phoneNumber)}`;
|
|
185
204
|
lastOutputValueRef.current = value;
|
|
186
|
-
onChange && onChange(value);
|
|
205
|
+
onChange && onChange(value, false);
|
|
187
206
|
}
|
|
188
207
|
|
|
189
208
|
useLayoutEffect(() => {
|
|
@@ -202,9 +221,14 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
202
221
|
const lineNumber = stripNonNumericAfterCountryCode(newPhoneNumber);
|
|
203
222
|
const outputValue = countryPrefix + lineNumber;
|
|
204
223
|
|
|
224
|
+
// Clear obfuscated state when user types manually
|
|
225
|
+
if (obfuscateValue) {
|
|
226
|
+
setObfuscateValue(false);
|
|
227
|
+
}
|
|
228
|
+
|
|
205
229
|
lastOutputValueRef.current = outputValue;
|
|
206
230
|
phoneNumber !== newPhoneNumber && setPhoneNumber(newPhoneNumber);
|
|
207
|
-
onChange && onChange(outputValue);
|
|
231
|
+
onChange && onChange(outputValue, false);
|
|
208
232
|
}
|
|
209
233
|
|
|
210
234
|
function togglePhoneBook(e: React.MouseEvent<HTMLButtonElement>) {
|
|
@@ -219,9 +243,15 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
219
243
|
setPhoneBookElement(null);
|
|
220
244
|
}
|
|
221
245
|
|
|
222
|
-
function handlePhoneBookOptionSelect(
|
|
246
|
+
function handlePhoneBookOptionSelect(
|
|
247
|
+
value: string,
|
|
248
|
+
_label: string | undefined,
|
|
249
|
+
_isSuggestion: boolean,
|
|
250
|
+
obfuscate: boolean
|
|
251
|
+
) {
|
|
223
252
|
// Update the phone number with the selected value
|
|
224
|
-
|
|
253
|
+
setObfuscateValue(obfuscate);
|
|
254
|
+
updatePhoneNumber(value, obfuscate);
|
|
225
255
|
closePhoneBook();
|
|
226
256
|
}
|
|
227
257
|
|
|
@@ -244,8 +274,22 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
244
274
|
return value;
|
|
245
275
|
}
|
|
246
276
|
|
|
277
|
+
function handleObfuscatedInputChange(newValue: string) {
|
|
278
|
+
// When user types on a obfuscated input, clear the obfuscated state and start fresh
|
|
279
|
+
// The newValue will be the digits the user typed (mask filters to valid input)
|
|
280
|
+
setShouldFocusAfterClear(true);
|
|
281
|
+
setObfuscateValue(false);
|
|
282
|
+
setPhoneNumber(newValue);
|
|
283
|
+
|
|
284
|
+
const countryPrefix = countryCodeMap.get(countryCode)?.prefix;
|
|
285
|
+
const lineNumber = stripNonNumericAfterCountryCode(newValue);
|
|
286
|
+
const outputValue = countryPrefix + lineNumber;
|
|
287
|
+
lastOutputValueRef.current = outputValue;
|
|
288
|
+
onChange && onChange(outputValue, false);
|
|
289
|
+
}
|
|
290
|
+
|
|
247
291
|
const updatePhoneNumber = useCallback(
|
|
248
|
-
(value: string) => {
|
|
292
|
+
(value: string, obfuscate = false) => {
|
|
249
293
|
const oldValue = lastOutputValueRef.current;
|
|
250
294
|
const countryInformation = getCountryCodeFromValue(
|
|
251
295
|
value,
|
|
@@ -259,7 +303,7 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
259
303
|
|
|
260
304
|
if (oldValue !== value) {
|
|
261
305
|
setPhoneNumber(phoneNumber);
|
|
262
|
-
onChange && onChange(value);
|
|
306
|
+
onChange && onChange(value, obfuscate);
|
|
263
307
|
}
|
|
264
308
|
},
|
|
265
309
|
[defaultCountry, selectedCountry, onChange]
|
|
@@ -269,6 +313,14 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
269
313
|
updatePhoneNumber(value);
|
|
270
314
|
}, [value, updatePhoneNumber]);
|
|
271
315
|
|
|
316
|
+
// Focus the input after transitioning from obfuscated to normal mode
|
|
317
|
+
useLayoutEffect(() => {
|
|
318
|
+
if (shouldFocusAfterClear && !obfuscateValue && internalInputRef.current) {
|
|
319
|
+
internalInputRef.current.focus();
|
|
320
|
+
setShouldFocusAfterClear(false);
|
|
321
|
+
}
|
|
322
|
+
}, [shouldFocusAfterClear, obfuscateValue]);
|
|
323
|
+
|
|
272
324
|
return (
|
|
273
325
|
<HStack
|
|
274
326
|
ref={ref}
|
|
@@ -280,25 +332,51 @@ export const PhoneNumberInput = React.forwardRef(function PhoneNumberInput(
|
|
|
280
332
|
className={clsx(styles['phone-number-input-select'], 'phone-number-input-select')}
|
|
281
333
|
ref={countryRef}
|
|
282
334
|
width="auto"
|
|
283
|
-
value={countryCode}
|
|
335
|
+
value={obfuscateValue ? '' : countryCode}
|
|
284
336
|
onChange={changeCountry}
|
|
285
|
-
disabled={disabled}
|
|
286
|
-
data-is-disabled={disabled}
|
|
337
|
+
disabled={disabled || obfuscateValue}
|
|
338
|
+
data-is-disabled={disabled || obfuscateValue}
|
|
339
|
+
data-is-obfuscated={obfuscateValue}
|
|
340
|
+
placeholder={obfuscateValue ? '––' : undefined}
|
|
287
341
|
>
|
|
288
342
|
{countryOptions}
|
|
289
343
|
</Select>
|
|
290
344
|
<HStack width="flex" className={clsx(styles['phone-number-input-container'])}>
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
345
|
+
{obfuscateValue ? (
|
|
346
|
+
<MaskInput
|
|
347
|
+
key="obfuscated"
|
|
348
|
+
ref={forkedInputRef}
|
|
349
|
+
value=""
|
|
350
|
+
mask={createObfuscatedMasks(currentMasks)}
|
|
351
|
+
onChange={handleObfuscatedInputChange}
|
|
352
|
+
disabled={disabled}
|
|
353
|
+
data-is-disabled={disabled}
|
|
354
|
+
data-has-phone-book={showPhoneBook}
|
|
355
|
+
data-is-obfuscated={true}
|
|
356
|
+
className={clsx(
|
|
357
|
+
styles['phone-number-input'],
|
|
358
|
+
styles['phone-number-input-obfuscated'],
|
|
359
|
+
'phone-number-input'
|
|
360
|
+
)}
|
|
361
|
+
preparePasteValue={() => ''}
|
|
362
|
+
prepareCopyValue={() => ''}
|
|
363
|
+
prepareCutValue={() => ''}
|
|
364
|
+
/>
|
|
365
|
+
) : (
|
|
366
|
+
<MaskInput
|
|
367
|
+
key="normal"
|
|
368
|
+
ref={forkedInputRef}
|
|
369
|
+
value={phoneNumber}
|
|
370
|
+
mask={currentMasks}
|
|
371
|
+
onChange={transformValue}
|
|
372
|
+
disabled={disabled}
|
|
373
|
+
data-is-disabled={disabled}
|
|
374
|
+
data-has-phone-book={showPhoneBook}
|
|
375
|
+
data-is-obfuscated={false}
|
|
376
|
+
className={clsx(styles['phone-number-input'], 'phone-number-input')}
|
|
377
|
+
preparePasteValue={preparePasteValue}
|
|
378
|
+
/>
|
|
379
|
+
)}
|
|
302
380
|
</HStack>
|
|
303
381
|
{showPhoneBook && (
|
|
304
382
|
<>
|
|
@@ -6,7 +6,12 @@ export interface SuggestionItemProps {
|
|
|
6
6
|
isFocused: boolean;
|
|
7
7
|
isSelected: boolean;
|
|
8
8
|
option: React.ReactElement;
|
|
9
|
-
onClick?: (
|
|
9
|
+
onClick?: (
|
|
10
|
+
value: string,
|
|
11
|
+
label: string,
|
|
12
|
+
isSuggestion: boolean,
|
|
13
|
+
obfuscate: boolean
|
|
14
|
+
) => void;
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
export function SuggestionItem({
|
|
@@ -43,7 +48,12 @@ export function SuggestionItem({
|
|
|
43
48
|
disabled={isDisabled}
|
|
44
49
|
onClick={() => {
|
|
45
50
|
if (!isDisabled && onClick) {
|
|
46
|
-
onClick(
|
|
51
|
+
onClick(
|
|
52
|
+
option.props.value,
|
|
53
|
+
option.props.label,
|
|
54
|
+
true,
|
|
55
|
+
option.props.obfuscate ?? false
|
|
56
|
+
);
|
|
47
57
|
}
|
|
48
58
|
}}
|
|
49
59
|
>
|
|
@@ -25,7 +25,8 @@ export interface SuggestionListProps
|
|
|
25
25
|
onOptionSelect?: (
|
|
26
26
|
value: string,
|
|
27
27
|
label: string | undefined,
|
|
28
|
-
isSuggestion: boolean
|
|
28
|
+
isSuggestion: boolean,
|
|
29
|
+
obfuscate: boolean
|
|
29
30
|
) => void;
|
|
30
31
|
noSuggestionMessage?: React.ReactNode;
|
|
31
32
|
trimCustomInput?: boolean;
|
|
@@ -112,7 +113,13 @@ export function SuggestionList({
|
|
|
112
113
|
const optionValue = option?.props.value || value;
|
|
113
114
|
|
|
114
115
|
requestAnimationFrame(() => {
|
|
115
|
-
onOptionSelect &&
|
|
116
|
+
onOptionSelect &&
|
|
117
|
+
onOptionSelect(
|
|
118
|
+
optionValue,
|
|
119
|
+
label,
|
|
120
|
+
isSuggestion,
|
|
121
|
+
option?.props.obfuscate ?? false
|
|
122
|
+
);
|
|
116
123
|
});
|
|
117
124
|
|
|
118
125
|
break;
|
|
@@ -126,7 +133,13 @@ export function SuggestionList({
|
|
|
126
133
|
}
|
|
127
134
|
|
|
128
135
|
requestAnimationFrame(() => {
|
|
129
|
-
onOptionSelect &&
|
|
136
|
+
onOptionSelect &&
|
|
137
|
+
onOptionSelect(
|
|
138
|
+
optionProps.value,
|
|
139
|
+
optionProps.label,
|
|
140
|
+
true,
|
|
141
|
+
optionProps.obfuscate ?? false
|
|
142
|
+
);
|
|
130
143
|
});
|
|
131
144
|
break;
|
|
132
145
|
}
|
|
@@ -260,6 +273,12 @@ export function SuggestionList({
|
|
|
260
273
|
const keywords = props.keywords?.map(k => k.toLocaleLowerCase()) || [];
|
|
261
274
|
const optionValue = String(props.value).toLocaleLowerCase();
|
|
262
275
|
const searchValue = value.toLocaleLowerCase();
|
|
276
|
+
const obfuscate = props.obfuscate ?? false;
|
|
277
|
+
|
|
278
|
+
// Obfuscated options can only be searched by label or keywords, not by value
|
|
279
|
+
if (obfuscate) {
|
|
280
|
+
return label.includes(searchValue) || keywords.some(k => k.includes(searchValue));
|
|
281
|
+
}
|
|
263
282
|
|
|
264
283
|
return (
|
|
265
284
|
label.includes(searchValue) ||
|
|
@@ -18,7 +18,7 @@ export const Footer = React.forwardRef<HTMLElement, FooterProps>(function Footer
|
|
|
18
18
|
<HStack
|
|
19
19
|
ref={ref}
|
|
20
20
|
as="footer"
|
|
21
|
-
className={clsx(styles.footer, className, '
|
|
21
|
+
className={clsx(styles.footer, className, 'tcn-footer')}
|
|
22
22
|
data-hierarchy={hierarchy}
|
|
23
23
|
data-size={size}
|
|
24
24
|
{...props}
|
package/src/layouts/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from './body/h_body.js';
|
|
2
|
+
export * from './body/v_body.js';
|
|
1
3
|
export * from './column/column.js';
|
|
2
4
|
export * from './divider/divider.js';
|
|
3
5
|
export * from './footer/footer.js';
|
|
@@ -8,5 +10,4 @@ export * from './list/list.js';
|
|
|
8
10
|
export * from './list/section_header.js';
|
|
9
11
|
export * from './sidebar_end/sidebar_end.js';
|
|
10
12
|
export * from './sidebar_start/sidebar_start.js';
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './body/v_body.js';
|
|
13
|
+
export * from './utility_bar/utility_bar.js';
|