Skip to content

Commit

Permalink
feat: add Zod schema for Shadows
Browse files Browse the repository at this point in the history
  • Loading branch information
migueloller authored and fikrikarim committed Apr 9, 2024
1 parent 5bd9b5f commit 6b62ab6
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-tigers-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@makeswift/prop-controllers': minor
---

Add Zod to `@makeswift/prop-controllers` and schemas for legacy Shadows prop controller.
3 changes: 2 additions & 1 deletion packages/prop-controllers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"test": "jest"
},
"dependencies": {
"ts-pattern": "^5.0.8"
"ts-pattern": "^5.0.8",
"zod": "^3.21.4"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
Expand Down
12 changes: 8 additions & 4 deletions packages/prop-controllers/src/data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export type ColorData = {
swatchId: string
alpha: number
}
import { z } from 'zod'

export const colorDataSchema = z.object({
swatchId: z.string(),
alpha: z.number(),
})

export type ColorData = z.infer<typeof colorDataSchema>
6 changes: 5 additions & 1 deletion packages/prop-controllers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ export * from './link'
export * from './prop-controllers'
export {
Shadows,
copyShadowsPropControllerData,
createShadowsPropControllerDataFromResponsiveShadowsData,
getShadowsPropControllerDataResponsiveShadowsData,
getShadowsPropControllerDataSwatchIds,
copyShadowsPropControllerData,
shadowsPropControllerDataSchema,
} from './shadows'
export type {
ResolveShadowsPropControllerValue,
ShadowData,
ShadowsData,
ShadowsDescriptor,
ShadowsPropControllerData,
} from './shadows'
21 changes: 20 additions & 1 deletion packages/prop-controllers/src/prop-controllers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { z } from 'zod'

export const Types = {
Link: 'Link',
Shadows: 'Shadows',
Expand All @@ -15,10 +17,27 @@ export type ResolveOptions<T extends Options<unknown>> = T extends Options<
? U
: never

export type Device = string
const deviceSchema = z.string()

export type Device = z.infer<typeof deviceSchema>

function createDeviceOverrideSchema<T extends z.ZodTypeAny>(
schema: T,
): z.ZodObject<{ deviceId: typeof deviceSchema; value: T }> {
return z.object({
deviceId: deviceSchema,
value: schema,
})
}

export type DeviceOverride<T> = { deviceId: Device; value: T }

export function createResponsiveValueSchema<T extends z.ZodTypeAny>(
schema: T,
): z.ZodArray<ReturnType<typeof createDeviceOverrideSchema<T>>> {
return z.array(createDeviceOverrideSchema(schema))
}

export type ResponsiveValue<T> = DeviceOverride<T>[]

export type ResponsiveValueType<T> = T extends ResponsiveValue<infer U>
Expand Down
78 changes: 58 additions & 20 deletions packages/prop-controllers/src/shadows.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,60 @@
import { match } from 'ts-pattern'
import { ColorData } from "./data"
import { colorDataSchema } from "./data"
import {
ControlDataTypeKey,
CopyContext,
ResolveOptions,
ResponsiveValue,
Types,
createResponsiveValueSchema,
} from './prop-controllers'
import { z } from 'zod'

type ShadowData = {
color?: ColorData | null
blurRadius?: number
spreadRadius?: number
offsetX?: number
offsetY?: number
inset?: boolean
}
const shadowDataSchema = z.object({
color: colorDataSchema.nullable().optional(),
blurRadius: z.number().optional(),
spreadRadius: z.number().optional(),
offsetX: z.number().optional(),
offsetY: z.number().optional(),
inset: z.boolean().optional(),
})

export type ShadowData = z.infer<typeof shadowDataSchema>

const shadowsDataSchema = z.array(
z.object({
id: z.string(),
payload: shadowDataSchema,
}),
)

export type ShadowsData = z.infer<typeof shadowsDataSchema>

type ShadowsData = { id: string; payload: ShadowData }[]
const responsiveShadowsDataSchema =
createResponsiveValueSchema(shadowsDataSchema)

type ResponsiveShadowsData = ResponsiveValue<ShadowsData>
type ResponsiveShadowsData = z.infer<typeof responsiveShadowsDataSchema>

type ShadowsPropControllerDataV0 = ResponsiveShadowsData
const shadowsPropControllerDataV0Schema = responsiveShadowsDataSchema

type ShadowsPropControllerDataV0 = z.infer<
typeof shadowsPropControllerDataV0Schema
>

const ShadowsPropControllerDataV1Type = 'prop-controllers::shadows::v1'

type ShadowsPropControllerDataV1 = {
[ControlDataTypeKey]: typeof ShadowsPropControllerDataV1Type
value: ResponsiveShadowsData
}
const shadowsPropControllerDataV1Schema = z.object({
[ControlDataTypeKey]: z.literal(ShadowsPropControllerDataV1Type),
value: responsiveShadowsDataSchema,
})

export const shadowsPropControllerDataSchema = z.union([
shadowsPropControllerDataV0Schema,
shadowsPropControllerDataV1Schema,
])

export type ShadowsPropControllerData =
| ShadowsPropControllerDataV0
| ShadowsPropControllerDataV1
export type ShadowsPropControllerData = z.infer<
typeof shadowsPropControllerDataSchema
>

export const ShadowsPropControllerFormat = {
ClassName: 'makeswift::prop-controllers::shadows::format::class-name',
Expand Down Expand Up @@ -105,6 +127,22 @@ export function getShadowsPropControllerDataResponsiveShadowsData(
.otherwise((v0) => v0)
}

export function createShadowsPropControllerDataFromResponsiveShadowsData(
definition: ShadowsDescriptor,
responsiveShadowsData: ResponsiveShadowsData,
): ShadowsPropControllerData {
return match(definition)
.with(
{ version: 1 },
() =>
({
[ControlDataTypeKey]: ShadowsPropControllerDataV1Type,
value: responsiveShadowsData,
} as const),
)
.otherwise(() => responsiveShadowsData)
}

export function getShadowsPropControllerDataSwatchIds(
data: ShadowsPropControllerData | null | undefined,
): string[] {
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6b62ab6

Please sign in to comment.