Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Add `corex` to your `mix.exs` dependencies:
```elixir
def deps do
[
{:corex, "~> 0.1.0-alpha.22"}
{:corex, "~> 0.1.0-alpha.23"}
]
end
```
Expand Down
69 changes: 69 additions & 0 deletions assets/components/angle-slider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { connect, machine, type Props, type Api } from "@zag-js/angle-slider";
import { VanillaMachine, normalizeProps } from "@zag-js/vanilla";
import { Component } from "../lib/core";

export class AngleSlider extends Component<Props, Api> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initMachine(props: Props): VanillaMachine<any> {
return new VanillaMachine(machine, props);
}

initApi(): Api {
return connect(this.machine.service, normalizeProps);
}

render(): void {
const rootEl =
this.el.querySelector<HTMLElement>('[data-scope="angle-slider"][data-part="root"]') ??
this.el;
this.spreadProps(rootEl, this.api.getRootProps());

const labelEl = this.el.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="label"]'
);
if (labelEl) this.spreadProps(labelEl, this.api.getLabelProps());

const hiddenInputEl = this.el.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="hidden-input"]'
);
if (hiddenInputEl) this.spreadProps(hiddenInputEl, this.api.getHiddenInputProps());

const controlEl = this.el.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="control"]'
);
if (controlEl) this.spreadProps(controlEl, this.api.getControlProps());

const thumbEl = this.el.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="thumb"]'
);
if (thumbEl) this.spreadProps(thumbEl, this.api.getThumbProps());

const valueTextEl = this.el.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="value-text"]'
);
if (valueTextEl) {
this.spreadProps(valueTextEl, this.api.getValueTextProps());
const valueSpan = valueTextEl.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="value"]'
);
if (valueSpan && valueSpan.textContent !== String(this.api.value)) {
valueSpan.textContent = String(this.api.value);
}
}

const markerGroupEl = this.el.querySelector<HTMLElement>(
'[data-scope="angle-slider"][data-part="marker-group"]'
);
if (markerGroupEl) this.spreadProps(markerGroupEl, this.api.getMarkerGroupProps());

this.el
.querySelectorAll<HTMLElement>('[data-scope="angle-slider"][data-part="marker"]')
.forEach((markerEl) => {
const valueStr = markerEl.dataset.value;
if (valueStr == null) return;
const value = Number(valueStr);
if (Number.isNaN(value)) return;
this.spreadProps(markerEl, this.api.getMarkerProps({ value }));
});
}
}
39 changes: 39 additions & 0 deletions assets/components/avatar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { connect, machine, type Props, type Api } from "@zag-js/avatar";
import { VanillaMachine, normalizeProps } from "@zag-js/vanilla";
import { Component } from "../lib/core";

export class Avatar extends Component<Props, Api> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initMachine(props: Props): VanillaMachine<any> {
return new VanillaMachine(machine, props);
}

initApi(): Api {
return connect(this.machine.service, normalizeProps);
}

render(): void {
const rootEl =
this.el.querySelector<HTMLElement>('[data-scope="avatar"][data-part="root"]') ?? this.el;
this.spreadProps(rootEl, this.api.getRootProps());

const imageEl = this.el.querySelector<HTMLElement>('[data-scope="avatar"][data-part="image"]');
if (imageEl) this.spreadProps(imageEl, this.api.getImageProps());

const fallbackEl = this.el.querySelector<HTMLElement>(
'[data-scope="avatar"][data-part="fallback"]'
);
if (fallbackEl) this.spreadProps(fallbackEl, this.api.getFallbackProps());

const skeletonEl = this.el.querySelector<HTMLElement>(
'[data-scope="avatar"][data-part="skeleton"]'
);
if (skeletonEl) {
const state = this.machine.service.state;
const loaded = state.matches("loaded");
const error = state.matches("error");
skeletonEl.hidden = loaded || error;
skeletonEl.setAttribute("data-state", loaded || error ? "hidden" : "visible");
}
}
}
73 changes: 73 additions & 0 deletions assets/components/carousel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { connect, machine, type Props, type Api } from "@zag-js/carousel";
import type { ItemProps, IndicatorProps } from "@zag-js/carousel";
import { VanillaMachine, normalizeProps } from "@zag-js/vanilla";
import { Component } from "../lib/core";

export class Carousel extends Component<Props, Api> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initMachine(props: Props): VanillaMachine<any> {
return new VanillaMachine(machine, props);
}

initApi(): Api {
return connect(this.machine.service, normalizeProps);
}

render(): void {
const rootEl =
this.el.querySelector<HTMLElement>('[data-scope="carousel"][data-part="root"]') ?? this.el;
this.spreadProps(rootEl, this.api.getRootProps());

const controlEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="control"]'
);
if (controlEl) this.spreadProps(controlEl, this.api.getControlProps());

const itemGroupEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="item-group"]'
);
if (itemGroupEl) this.spreadProps(itemGroupEl, this.api.getItemGroupProps());

const slideCount = Number(this.el.dataset.slideCount) || 0;
for (let i = 0; i < slideCount; i++) {
const itemEl = this.el.querySelector<HTMLElement>(
`[data-scope="carousel"][data-part="item"][data-index="${i}"]`
);
if (itemEl) this.spreadProps(itemEl, this.api.getItemProps({ index: i } as ItemProps));
}

const prevTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="prev-trigger"]'
);
if (prevTriggerEl) this.spreadProps(prevTriggerEl, this.api.getPrevTriggerProps());

const nextTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="next-trigger"]'
);
if (nextTriggerEl) this.spreadProps(nextTriggerEl, this.api.getNextTriggerProps());

const autoplayTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="autoplay-trigger"]'
);
if (autoplayTriggerEl) this.spreadProps(autoplayTriggerEl, this.api.getAutoplayTriggerProps());

const indicatorGroupEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="indicator-group"]'
);
if (indicatorGroupEl) this.spreadProps(indicatorGroupEl, this.api.getIndicatorGroupProps());

const indicatorCount = this.api.pageSnapPoints.length;
for (let i = 0; i < indicatorCount; i++) {
const indicatorEl = this.el.querySelector<HTMLElement>(
`[data-scope="carousel"][data-part="indicator"][data-index="${i}"]`
);
if (indicatorEl)
this.spreadProps(indicatorEl, this.api.getIndicatorProps({ index: i } as IndicatorProps));
}

const progressTextEl = this.el.querySelector<HTMLElement>(
'[data-scope="carousel"][data-part="progress-text"]'
);
if (progressTextEl) this.spreadProps(progressTextEl, this.api.getProgressTextProps());
}
}
2 changes: 1 addition & 1 deletion assets/components/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class Combobox extends Component<Props, Api> {
itemToValue: (item: ComboboxItem) => item.id ?? "",
itemToString: (item: ComboboxItem) => item.label,
isItemDisabled: (item: ComboboxItem) => item.disabled ?? false,
groupBy: (item: ComboboxItem) => item.group,
groupBy: (item: ComboboxItem) => item.group ?? "",
});
}

Expand Down
53 changes: 53 additions & 0 deletions assets/components/editable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { connect, machine, type Props, type Api } from "@zag-js/editable";
import { VanillaMachine, normalizeProps } from "@zag-js/vanilla";
import { Component } from "../lib/core";

export class Editable extends Component<Props, Api> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initMachine(props: Props): VanillaMachine<any> {
return new VanillaMachine(machine, props);
}

initApi(): Api {
return connect(this.machine.service, normalizeProps);
}

render(): void {
const rootEl =
this.el.querySelector<HTMLElement>('[data-scope="editable"][data-part="root"]') ?? this.el;
this.spreadProps(rootEl, this.api.getRootProps());

const areaEl = this.el.querySelector<HTMLElement>('[data-scope="editable"][data-part="area"]');
if (areaEl) this.spreadProps(areaEl, this.api.getAreaProps());

const labelEl = this.el.querySelector<HTMLElement>(
'[data-scope="editable"][data-part="label"]'
);
if (labelEl) this.spreadProps(labelEl, this.api.getLabelProps());

const inputEl = this.el.querySelector<HTMLElement>(
'[data-scope="editable"][data-part="input"]'
);
if (inputEl) this.spreadProps(inputEl, this.api.getInputProps());

const previewEl = this.el.querySelector<HTMLElement>(
'[data-scope="editable"][data-part="preview"]'
);
if (previewEl) this.spreadProps(previewEl, this.api.getPreviewProps());

const editTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="editable"][data-part="edit-trigger"]'
);
if (editTriggerEl) this.spreadProps(editTriggerEl, this.api.getEditTriggerProps());

const submitTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="editable"][data-part="submit-trigger"]'
);
if (submitTriggerEl) this.spreadProps(submitTriggerEl, this.api.getSubmitTriggerProps());

const cancelTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="editable"][data-part="cancel-trigger"]'
);
if (cancelTriggerEl) this.spreadProps(cancelTriggerEl, this.api.getCancelTriggerProps());
}
}
83 changes: 83 additions & 0 deletions assets/components/floating-panel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { connect, machine, type Props, type Api } from "@zag-js/floating-panel";
import type { ResizeTriggerProps, StageTriggerProps } from "@zag-js/floating-panel";
import { VanillaMachine, normalizeProps } from "@zag-js/vanilla";
import { Component } from "../lib/core";

export class FloatingPanel extends Component<Props, Api> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initMachine(props: Props): VanillaMachine<any> {
return new VanillaMachine(machine, props);
}

initApi(): Api {
return connect(this.machine.service, normalizeProps);
}

render(): void {
const triggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="trigger"]'
);
if (triggerEl) this.spreadProps(triggerEl, this.api.getTriggerProps());

const positionerEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="positioner"]'
);
if (positionerEl) this.spreadProps(positionerEl, this.api.getPositionerProps());

const contentEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="content"]'
);
if (contentEl) this.spreadProps(contentEl, this.api.getContentProps());

const titleEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="title"]'
);
if (titleEl) this.spreadProps(titleEl, this.api.getTitleProps());

const headerEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="header"]'
);
if (headerEl) this.spreadProps(headerEl, this.api.getHeaderProps());

const bodyEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="body"]'
);
if (bodyEl) this.spreadProps(bodyEl, this.api.getBodyProps());

const dragTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="drag-trigger"]'
);
if (dragTriggerEl) this.spreadProps(dragTriggerEl, this.api.getDragTriggerProps());

const resizeAxes = ["s", "w", "e", "n", "sw", "nw", "se", "ne"] as const;
resizeAxes.forEach((axis) => {
const resizeEl = this.el.querySelector<HTMLElement>(
`[data-scope="floating-panel"][data-part="resize-trigger"][data-axis="${axis}"]`
);
if (resizeEl)
this.spreadProps(resizeEl, this.api.getResizeTriggerProps({ axis } as ResizeTriggerProps));
});

const closeTriggerEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="close-trigger"]'
);
if (closeTriggerEl) this.spreadProps(closeTriggerEl, this.api.getCloseTriggerProps());

const controlEl = this.el.querySelector<HTMLElement>(
'[data-scope="floating-panel"][data-part="control"]'
);
if (controlEl) this.spreadProps(controlEl, this.api.getControlProps());

const stages = ["minimized", "maximized", "default"] as const;
stages.forEach((stage) => {
const stageTriggerEl = this.el.querySelector<HTMLElement>(
`[data-scope="floating-panel"][data-part="stage-trigger"][data-stage="${stage}"]`
);
if (stageTriggerEl)
this.spreadProps(
stageTriggerEl,
this.api.getStageTriggerProps({ stage } as StageTriggerProps)
);
});
}
}
Loading
Loading