parent
f62b32677c
commit
5a6193d365
@ -0,0 +1,32 @@
|
|||||||
|
// RatingGroup — eidos compound API, disciplined option C.
|
||||||
|
//
|
||||||
|
// import { RatingGroup } from '$uix/eidos/components/rating-group';
|
||||||
|
//
|
||||||
|
// <RatingGroup bind:value let:items>
|
||||||
|
// {#each items as item}
|
||||||
|
// <RatingGroup.Item index={item.index}>★</RatingGroup.Item>
|
||||||
|
// {/each}
|
||||||
|
// </RatingGroup>
|
||||||
|
import RatingGroupRoot from './rating-group.svelte';
|
||||||
|
import Item from './rating-group-item.svelte';
|
||||||
|
|
||||||
|
type RatingGroupNamespace = typeof RatingGroupRoot & {
|
||||||
|
Item: typeof Item;
|
||||||
|
};
|
||||||
|
|
||||||
|
const RatingGroup = RatingGroupRoot as RatingGroupNamespace;
|
||||||
|
RatingGroup.Item = Item;
|
||||||
|
|
||||||
|
export { RatingGroup };
|
||||||
|
|
||||||
|
export default RatingGroup;
|
||||||
|
|
||||||
|
export type {
|
||||||
|
RatingGroupProps,
|
||||||
|
RatingGroupItemProps as ItemProps,
|
||||||
|
RatingGroupSize,
|
||||||
|
RatingGroupProviderSnippetProps as ProviderSnippetProps,
|
||||||
|
RatingGroupItemSnippetProps as ItemSnippetProps,
|
||||||
|
RatingItemDescriptor,
|
||||||
|
RatingItemState
|
||||||
|
} from './types';
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Item as SomaRatingGroupItem } from '$soma/components/rating-group';
|
||||||
|
import type { RatingGroupItemProps } from './types';
|
||||||
|
|
||||||
|
let { children, ...rest }: RatingGroupItemProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SomaRatingGroupItem {...rest}>
|
||||||
|
{#snippet children(snippetProps)}
|
||||||
|
{@render children?.(snippetProps)}
|
||||||
|
{/snippet}
|
||||||
|
</SomaRatingGroupItem>
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
[data-rating-group] {
|
||||||
|
--_rating-group-gap: var(--rating-group-gap-md);
|
||||||
|
--_rating-group-item-size: var(--rating-group-item-size-md);
|
||||||
|
--_rating-group-font-size: var(--rating-group-font-size-md);
|
||||||
|
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--_rating-group-gap);
|
||||||
|
color: var(--rating-group-item-color-inactive);
|
||||||
|
font-family: var(--rating-group-font-family);
|
||||||
|
font-size: var(--_rating-group-font-size);
|
||||||
|
line-height: var(--rating-group-line-height);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group][data-size='sm'] {
|
||||||
|
--_rating-group-gap: var(--rating-group-gap-sm);
|
||||||
|
--_rating-group-item-size: var(--rating-group-item-size-sm);
|
||||||
|
--_rating-group-font-size: var(--rating-group-font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group][data-size='lg'] {
|
||||||
|
--_rating-group-gap: var(--rating-group-gap-lg);
|
||||||
|
--_rating-group-item-size: var(--rating-group-item-size-lg);
|
||||||
|
--_rating-group-font-size: var(--rating-group-font-size-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group][data-orientation='vertical'] {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group]:focus-visible {
|
||||||
|
border-radius: var(--rating-group-focus-radius);
|
||||||
|
box-shadow: var(--rating-group-focus-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group][data-disabled] {
|
||||||
|
opacity: var(--rating-group-disabled-opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group-item] {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
inline-size: var(--_rating-group-item-size);
|
||||||
|
block-size: var(--_rating-group-item-size);
|
||||||
|
color: var(--rating-group-item-color-inactive);
|
||||||
|
cursor: pointer;
|
||||||
|
transition:
|
||||||
|
color var(--rating-group-transition-duration) var(--rating-group-transition-ease),
|
||||||
|
transform var(--rating-group-transition-duration) var(--rating-group-transition-ease);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group-item][data-state='active'] {
|
||||||
|
color: var(--rating-group-item-color-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group-item][data-state='partial'] {
|
||||||
|
color: var(--rating-group-item-color-partial);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group-item]:hover:not([data-disabled]):not([data-readonly]) {
|
||||||
|
transform: translateY(var(--rating-group-item-hover-offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group-item][data-disabled],
|
||||||
|
[data-rating-group-item][data-readonly] {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-rating-group-item] > :where(svg) {
|
||||||
|
inline-size: 100%;
|
||||||
|
block-size: 100%;
|
||||||
|
fill: currentColor;
|
||||||
|
stroke: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
[data-rating-group-item] {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
/**
|
||||||
|
* Eidos `<RatingGroup>` — visual wrapper over Soma's rating primitive.
|
||||||
|
* Soma owns slider semantics, pointer preview and item state; Eidos adds `size`.
|
||||||
|
*/
|
||||||
|
import { ActiveEidos } from '$uix/eidos';
|
||||||
|
import { Provider as SomaRatingGroupProvider } from '$soma/components/rating-group';
|
||||||
|
import type { RatingGroupProps } from './types';
|
||||||
|
|
||||||
|
let { size = 'md', value = $bindable(0), children, ...rest }: RatingGroupProps = $props();
|
||||||
|
|
||||||
|
const eidos = ActiveEidos.require();
|
||||||
|
const resolvedSize = $derived(eidos.resolve(size, 'md'));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SomaRatingGroupProvider {...rest} bind:value data-size={resolvedSize}>
|
||||||
|
{#snippet children(snippetProps)}
|
||||||
|
{@render children?.(snippetProps)}
|
||||||
|
{/snippet}
|
||||||
|
</SomaRatingGroupProvider>
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import type {
|
||||||
|
ItemProps as SomaRatingGroupItemProps,
|
||||||
|
ProviderProps as SomaRatingGroupProviderProps,
|
||||||
|
ProviderSnippetProps as RatingGroupProviderSnippetProps,
|
||||||
|
RatingItemDescriptor,
|
||||||
|
RatingItemState,
|
||||||
|
ItemSnippetProps as RatingGroupItemSnippetProps
|
||||||
|
} from '$soma/components/rating-group';
|
||||||
|
import type { ResponsiveProp, Size } from '$uix/eidos/lib/types';
|
||||||
|
|
||||||
|
export type RatingGroupSize = Extract<Size, 'sm' | 'md' | 'lg'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Props for the eidos `<RatingGroup>`.
|
||||||
|
*
|
||||||
|
* Extends Soma's rating slider with visual sizing only. Value, hover preview,
|
||||||
|
* active/partial/inactive item state and ARIA are owned by Soma.
|
||||||
|
*/
|
||||||
|
export type RatingGroupProps = SomaRatingGroupProviderProps & {
|
||||||
|
/** Visual size. Accepts a responsive map resolved by ActiveEidos. @default 'md' */
|
||||||
|
size?: ResponsiveProp<RatingGroupSize>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RatingGroupItemProps = SomaRatingGroupItemProps;
|
||||||
|
export type {
|
||||||
|
RatingGroupProviderSnippetProps,
|
||||||
|
RatingGroupItemSnippetProps,
|
||||||
|
RatingItemDescriptor,
|
||||||
|
RatingItemState
|
||||||
|
};
|
||||||
Loading…
Reference in new issue