diff --git a/src/components/gili/layout/Control.module.scss b/src/components/gili/layout/Control.module.scss index 61f006337..9a7eeee3a 100644 --- a/src/components/gili/layout/Control.module.scss +++ b/src/components/gili/layout/Control.module.scss @@ -1,4 +1,4 @@ -@layer ui.input { +@layer ui.layout { .control { display: grid; grid-template-areas: "input label"; diff --git a/src/components/gili/layout/Interactive.module.scss b/src/components/gili/layout/Interactive.module.scss index e554808c2..2f45e9c70 100644 --- a/src/components/gili/layout/Interactive.module.scss +++ b/src/components/gili/layout/Interactive.module.scss @@ -1,4 +1,4 @@ -@layer ui.input { +@layer ui.layout { .interactive { position: relative; diff --git a/src/components/gili/layout/Island.module.scss b/src/components/gili/layout/Island.module.scss new file mode 100644 index 000000000..5966b9ed2 --- /dev/null +++ b/src/components/gili/layout/Island.module.scss @@ -0,0 +1,38 @@ +@layer ui.layout { + .island { + padding: 0.5rem; + border-radius: var(--border-radius-island); + background-color: var(--color-background); + box-shadow: 0px 1px 4px 0px #0000000D; + } + + .description { + display: block; + + padding: 0.5rem 1rem; + + font-size: 0.875rem; + line-height: 1rem; + color: var(--color-text-secondary); + overflow-wrap: anywhere; + } + + .text { + display: block; + padding: 0.5rem 1rem; + line-height: 1.25rem; + overflow-wrap: anywhere; + } + + .island + .island { + margin-top: 1rem; + } + + .island + .description { + margin-top: 0.5rem; + } + + .description + .island { + margin-top: 1rem; + } +} diff --git a/src/components/gili/layout/Island.tsx b/src/components/gili/layout/Island.tsx new file mode 100644 index 000000000..b7601f319 --- /dev/null +++ b/src/components/gili/layout/Island.tsx @@ -0,0 +1,46 @@ +import buildClassName from '../../../util/buildClassName'; + +import styles from './Island.module.scss'; + +type OwnProps = React.HTMLAttributes & { + children: React.ReactNode; +}; + +const Island = ({ className, children, ...otherProps }: OwnProps) => { + return ( +
+ {children} +
+ ); +}; + +const IslandDescription = ({ className, children, ...otherProps }: OwnProps) => { + return ( +
+ {children} +
+ ); +}; + +const IslandText = ({ className, children, ...otherProps }: OwnProps) => { + return ( +
+ {children} +
+ ); +}; + +export default Island; +export { + IslandDescription, + IslandText, +}; diff --git a/src/components/gili/layout/Surface.module.scss b/src/components/gili/layout/Surface.module.scss new file mode 100644 index 000000000..a7a4dd069 --- /dev/null +++ b/src/components/gili/layout/Surface.module.scss @@ -0,0 +1,15 @@ +@use '../../../styles/mixins'; + +@layer ui.layout { + .root { + padding-inline: 1rem; + background-color: var(--color-background-secondary); + } + + .scrollable { + scrollbar-gutter: stable; + overflow-y: auto; + + @include mixins.adapt-padding-to-scrollbar(1rem); + } +} diff --git a/src/components/gili/layout/Surface.tsx b/src/components/gili/layout/Surface.tsx new file mode 100644 index 000000000..0e1ad6bc0 --- /dev/null +++ b/src/components/gili/layout/Surface.tsx @@ -0,0 +1,33 @@ +import buildClassName from '../../../util/buildClassName'; + +import styles from './Surface.module.scss'; + +type OwnProps = React.HTMLAttributes & { + scrollable?: boolean; + children: React.ReactNode; +}; + +const Surface = ({ + scrollable, + className, + children, + ...otherProps +}: OwnProps) => { + const isScrollable = Boolean(scrollable); + + return ( +
+ {children} +
+ ); +}; + +export default Surface; diff --git a/src/components/test/demo/FieldDemo.module.scss b/src/components/test/demo/FieldDemo.module.scss new file mode 100644 index 000000000..ccd1c669b --- /dev/null +++ b/src/components/test/demo/FieldDemo.module.scss @@ -0,0 +1,81 @@ +.root { + height: 100vh; +} + +.content { + columns: 28rem 2; + column-gap: 2rem; + padding-block: 2rem; +} + +.fullWidth { + column-span: all; + break-inside: avoid; +} + +.title { + margin: 0 0 1.5rem; +} + +.layoutPreview, +.section { + break-inside: avoid; + margin-bottom: 2rem; +} + +.layoutPreview { + display: flex; + flex-direction: column; +} + +.sectionTitle { + margin: 0 0 0.5rem; + + font-size: 0.875rem; + font-weight: var(--font-weight-medium); + color: var(--color-text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.sectionContent { + overflow: hidden; + border: 1px solid var(--color-borders-input); + border-radius: 0.75rem; +} + +.sectionContentNoBorder { + border: 0; + border-radius: 0; +} + +.barePrimitives { + display: flex; + flex-wrap: wrap; + gap: 1rem; + align-items: center; + + padding: 1rem; +} + +.previewCard { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.previewLabel { + font-size: 0.75rem; + font-weight: var(--font-weight-semibold); + color: var(--color-text-secondary); + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.previewText { + line-height: 1.25rem; +} + +.bareControl { + padding: 0.5rem 1rem; +} diff --git a/src/components/test/FieldTest.tsx b/src/components/test/demo/FieldDemo.tsx similarity index 86% rename from src/components/test/FieldTest.tsx rename to src/components/test/demo/FieldDemo.tsx index 5b34cedc5..971c88a50 100644 --- a/src/components/test/FieldTest.tsx +++ b/src/components/test/demo/FieldDemo.tsx @@ -1,40 +1,48 @@ /* eslint-disable @stylistic/max-len */ -import { useState } from '../../lib/teact/teact'; +import { useState } from '../../../lib/teact/teact'; -import buildStyle from '../../util/buildStyle'; +import buildClassName from '../../../util/buildClassName'; import Control, { ControlAfter, ControlBefore, ControlDescription, ControlLabel, -} from '../gili/layout/Control'; -import Interactive from '../gili/layout/Interactive'; -import Checkbox from '../gili/primitives/Checkbox'; -import Radio from '../gili/primitives/Radio'; -import Switch from '../gili/primitives/Switch'; -import CheckboxField from '../gili/templates/CheckboxField'; -import SwitchField from '../gili/templates/SwitchField'; +} from '../../gili/layout/Control'; +import Interactive from '../../gili/layout/Interactive'; +import Island, { + IslandDescription, + IslandText, +} from '../../gili/layout/Island'; +import Surface from '../../gili/layout/Surface'; +import Checkbox from '../../gili/primitives/Checkbox'; +import Radio from '../../gili/primitives/Radio'; +import Switch from '../../gili/primitives/Switch'; +import CheckboxField from '../../gili/templates/CheckboxField'; +import SwitchField from '../../gili/templates/SwitchField'; -function Section({ title, children, noBorder }: { title: string; children: any; noBorder?: boolean }) { +import styles from './FieldDemo.module.scss'; + +type SectionProps = { + title: string; + children: React.ReactNode; + noBorder?: boolean; +}; + +function Section({ title, children, noBorder }: SectionProps) { return ( -
-

- {title} -

-
- {children} -
+
+ +

{title}

+
+ {children} +
+
); } -const FieldTest = () => { +const FieldDemo = () => { const [check1, setCheck1] = useState(false); const [check2, setCheck2] = useState(true); const [check3, setCheck3] = useState(false); @@ -65,13 +73,50 @@ const FieldTest = () => { const [switch4, setSwitch4] = useState(true); return ( -
-
-

Control Component Test

+ +
+

Control Component Test

+ +
+ + +

Surface + Islands

+
+ Island + + Regular background, island radius, and 0.5rem padding. + +
+
+
+ + IslandDescription stays attached to the island above it, and the next island starts 1rem lower. + + + +
+ Island After Description + + This island verifies the description-to-island spacing rule. + +
+
+
+ + +
+ Island After Island + + This island verifies the direct island-to-island 1rem gap. + +
+
+
+
{/* Bare primitives */}
-
+
@@ -481,7 +526,7 @@ const FieldTest = () => { {/* Control without Interactive */}
-
+
Bare field, custom container @@ -494,8 +539,8 @@ const FieldTest = () => {
-
+ ); }; -export default FieldTest; +export default FieldDemo; diff --git a/src/components/test/TestDateFormat.module.scss b/src/components/test/demo/TestDateFormat.module.scss similarity index 100% rename from src/components/test/TestDateFormat.module.scss rename to src/components/test/demo/TestDateFormat.module.scss diff --git a/src/components/test/TestDateFormat.tsx b/src/components/test/demo/TestDateFormat.tsx similarity index 95% rename from src/components/test/TestDateFormat.tsx rename to src/components/test/demo/TestDateFormat.tsx index eabeda714..3b57e5d1d 100644 --- a/src/components/test/TestDateFormat.tsx +++ b/src/components/test/demo/TestDateFormat.tsx @@ -1,9 +1,9 @@ -import type { FormatDateTimeOptions } from '../../util/localization/dateFormat'; +import type { FormatDateTimeOptions } from '../../../util/localization/dateFormat'; -import buildClassName from '../../util/buildClassName'; -import { formatDateTime, formatMessageListDate } from '../../util/localization/dateFormat'; +import buildClassName from '../../../util/buildClassName'; +import { formatDateTime, formatMessageListDate } from '../../../util/localization/dateFormat'; -import useLang from '../../hooks/useLang'; +import useLang from '../../../hooks/useLang'; import styles from './TestDateFormat.module.scss'; diff --git a/src/index.html b/src/index.html index b634be321..b7c02ecd5 100644 --- a/src/index.html +++ b/src/index.html @@ -54,7 +54,7 @@