-
-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
2,763 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
.time-field { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 4px; | ||
} | ||
|
||
.time-field__label { | ||
color: hsl(240 6% 10%); | ||
font-size: 14px; | ||
font-weight: 500; | ||
user-select: none; | ||
} | ||
|
||
.time-field__field { | ||
display: flex; | ||
padding: 4px 8px; | ||
border-radius: 6px; | ||
width: 150px; | ||
white-space: nowrap; | ||
forced-color-adjust: none; | ||
background-color: #fff; | ||
border: 1px solid hsl(240 6% 90%); | ||
color: hsl(240 4% 16%); | ||
font-size: 14px; | ||
} | ||
|
||
.time-field__field:focus-within { | ||
outline: 2px solid hsl(200 98% 39%); | ||
outline-offset: -1px; | ||
} | ||
|
||
.time-field__segment { | ||
padding: 0 2px; | ||
font-variant-numeric: tabular-nums; | ||
text-align: end; | ||
} | ||
|
||
.time-field__segment[data-type="literal"] { | ||
padding: 0; | ||
} | ||
|
||
.time-field__segment[data-placeholder] { | ||
color: hsl(240 4% 46%); | ||
font-style: italic; | ||
} | ||
|
||
.time-field__segment:focus { | ||
color: #fff !important; | ||
background: hsl(200 98% 39%); | ||
outline: none; | ||
border-radius: 4px; | ||
} | ||
|
||
.time-field__segment::selection { | ||
background-color: transparent; | ||
} | ||
|
||
.time-field__description { | ||
color: hsl(240 5% 26%); | ||
font-size: 12px; | ||
user-select: none; | ||
} | ||
|
||
.time-field__error-message { | ||
color: hsl(0 72% 51%); | ||
font-size: 12px; | ||
user-select: none; | ||
} | ||
|
||
[data-kb-theme="dark"] .time-field__label { | ||
color: hsl(240 5% 84%); | ||
} | ||
|
||
[data-kb-theme="dark"] .time-field__field { | ||
background-color: hsl(240 4% 16%); | ||
border: 1px solid hsl(240 5% 34%); | ||
color: hsl(0 100% 100% / 0.9); | ||
} | ||
|
||
.time-field__field[data-invalid] { | ||
border-color: hsl(0 72% 51%); | ||
outline-color: hsl(0 72% 51%); | ||
} | ||
|
||
[data-kb-theme="dark"] .time-field__segment[data-placeholder] { | ||
color: hsl(0 100% 100% / 0.5); | ||
} | ||
|
||
[data-kb-theme="dark"] .time-field__description { | ||
color: hsl(240 5% 65%); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
import { | ||
Time, | ||
getLocalTimeZone, | ||
parseZonedDateTime, | ||
toCalendarDateTime, | ||
today, | ||
} from "@internationalized/date"; | ||
import { createSignal } from "solid-js"; | ||
import { createDateFormatter } from "../../../../packages/core/src/i18n"; | ||
import { TimeField } from "../../../../packages/core/src/time-field"; | ||
import style from "./time-field.module.css"; | ||
|
||
export function BasicExample() { | ||
return ( | ||
<TimeField class={style["time-field"]}> | ||
<TimeField.Label class={style["time-field__label"]}> | ||
Event time | ||
</TimeField.Label> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function DefaultValueExample() { | ||
return ( | ||
<TimeField class={style["time-field"]} defaultValue={new Time(11, 45)}> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function ControlledValueExample() { | ||
const [value, setValue] = createSignal(new Time(9, 45)); | ||
|
||
const dateFormatter = createDateFormatter({ | ||
hour12: true, | ||
timeStyle: "short", | ||
}); | ||
|
||
return ( | ||
<> | ||
<TimeField | ||
class={style["time-field"]} | ||
value={value()} | ||
onChange={setValue} | ||
> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
<p class="not-prose text-sm mt-4"> | ||
Selected time:{" "} | ||
{value() | ||
? dateFormatter().format( | ||
toCalendarDateTime(today(getLocalTimeZone()), value()).toDate( | ||
getLocalTimeZone(), | ||
), | ||
) | ||
: "––"} | ||
</p> | ||
</> | ||
); | ||
} | ||
|
||
export function TimeZoneExample() { | ||
return ( | ||
<TimeField | ||
class={style["time-field"]} | ||
defaultValue={parseZonedDateTime("2022-11-07T00:45[America/Los_Angeles]")} | ||
> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function GranularityExample() { | ||
return ( | ||
<TimeField class={style["time-field"]} granularity="second"> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function MinMaxExample() { | ||
return ( | ||
<TimeField | ||
class={style["time-field"]} | ||
defaultValue={new Time(9, 45)} | ||
minValue={new Time(9)} | ||
maxValue={new Time(17)} | ||
> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
<TimeField.ErrorMessage class={style["time-field__error-message"]}> | ||
Select time between 9 AM and 5 PM. | ||
</TimeField.ErrorMessage> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function PlaceholderValueExample() { | ||
return ( | ||
<TimeField class={style["time-field"]} placeholderValue={new Time(9)}> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function HideTimeZoneExample() { | ||
return ( | ||
<TimeField | ||
class={style["time-field"]} | ||
defaultValue={parseZonedDateTime("2022-11-07T00:45[America/Los_Angeles]")} | ||
hideTimeZone | ||
> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function HourCycleExample() { | ||
return ( | ||
<TimeField class={style["time-field"]} hourCycle={24}> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function DescriptionExample() { | ||
return ( | ||
<TimeField class={style["time-field"]}> | ||
<TimeField.Label class={style["time-field__label"]}>Time</TimeField.Label> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
<TimeField.Description class={style["time-field__description"]}> | ||
Select a meeting time. | ||
</TimeField.Description> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function ErrorMessageExample() { | ||
const [value, setValue] = createSignal(undefined); | ||
|
||
return ( | ||
<TimeField | ||
class={style["time-field"]} | ||
value={value()} | ||
onChange={setValue} | ||
validationState={value() === undefined ? "invalid" : "valid"} | ||
> | ||
<TimeField.Label class={style["time-field__label"]}>Time</TimeField.Label> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
<TimeField.ErrorMessage class={style["time-field__error-message"]}> | ||
Please select a time. | ||
</TimeField.ErrorMessage> | ||
</TimeField> | ||
); | ||
} | ||
|
||
export function HTMLFormExample() { | ||
let formRef: HTMLFormElement | undefined; | ||
|
||
const onSubmit = (e: SubmitEvent) => { | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
|
||
const formData = new FormData(formRef); | ||
|
||
alert(JSON.stringify(Object.fromEntries(formData), null, 2)); | ||
}; | ||
|
||
return ( | ||
<form | ||
ref={formRef} | ||
onSubmit={onSubmit} | ||
class="flex flex-col items-center space-y-6" | ||
> | ||
<TimeField class={style["time-field"]} name="time"> | ||
<TimeField.Field class={style["time-field__field"]}> | ||
{(segment) => ( | ||
<TimeField.Segment | ||
class={style["time-field__segment"]} | ||
segment={segment()} | ||
/> | ||
)} | ||
</TimeField.Field> | ||
<TimeField.HiddenInput /> | ||
</TimeField> | ||
<div class="flex space-x-2"> | ||
<button type="reset" class="kb-button"> | ||
Reset | ||
</button> | ||
<button type="submit" class="kb-button-primary"> | ||
Submit | ||
</button> | ||
</div> | ||
</form> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.