123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- import { radio as radioDefinition } from '@formkit/inputs'
- import { has } from '@formkit/utils'
- import initializeFieldDefinition from '#shared/form/core/initializeFieldDefinition.ts'
- import formUpdaterTrigger from '#shared/form/features/formUpdaterTrigger.ts'
- import extendSchemaDefinition from '#shared/form/utils/extendSchemaDefinition.ts'
- import type { FormKitNode } from '@formkit/core'
- const addOptionCheckedDataAttribute = (node: FormKitNode) => {
- extendSchemaDefinition(node, 'wrapper', {
- attrs: {
- 'data-is-checked': {
- if: '$fns.isChecked($option.value)',
- then: 'true',
- else: undefined,
- },
- 'data-test-id': 'radio-label',
- },
- })
- }
- const addSubmitEvent = (node: FormKitNode) => {
- if (typeof node.props.onSubmit !== 'function') return
- extendSchemaDefinition(node, 'wrapper', {
- attrs: {
- onKeypress: (event: KeyboardEvent) => {
- if (event.key === 'Enter') {
- event.preventDefault()
- node.props.onSubmit.call(
- null,
- new SubmitEvent('submit', {
- submitter: event.target as HTMLElement,
- }),
- )
- }
- },
- },
- })
- }
- const addIconLabel = (node: FormKitNode) => {
- extendSchemaDefinition(node, 'label', {
- attrs: {
- id: null,
- },
- children: [
- {
- if: '$option.icon',
- $cmp: 'CommonIcon',
- props: {
- class: 'inline-flex ltr:mr-3 rtl:ml-3',
- name: '$option.icon',
- size: 'base',
- },
- },
- '$option.label',
- ],
- })
- }
- const handleButtonMode = (node: FormKitNode) => {
- const { props } = node
- node.addProps(['buttons'])
- const setClasses = (buttons: boolean) => {
- if (buttons) {
- props.optionsClass = 'flex flex-col grow space-y-2'
- props.optionClass = 'formkit-disabled:opacity-30'
- // this is needed to not show "required" label on buttons
- props.labelClass = '$reset'
- props.wrapperClass =
- 'items-center justify-center py-2 px-4 w-full h-14 text-lg font-normal text-white bg-gray-600 rounded-xl select-none formkit-is-checked:bg-white formkit-is-checked:text-black formkit-is-checked:font-semibold'
- props.inputClass = '$reset sr-only'
- props.decoratorClass = 'hidden'
- } else {
- props.inputClass =
- 'h-4 w-4 border-[1.5px] border-white rounded-full bg-transparent focus:border-blue focus:bg-blue-highlight checked:focus:color-blue checked:bg-blue checked:border-blue checked:focus:bg-blue checked:hover:bg-blue'
- }
- }
- node.on('created', () => {
- if (!has(props, 'buttons')) {
- props.buttons = false
- }
- setClasses(props.buttons)
- node.on('prop:buttons', ({ payload }) => {
- setClasses(payload)
- })
- })
- }
- initializeFieldDefinition(radioDefinition, {
- features: [
- addOptionCheckedDataAttribute,
- addSubmitEvent,
- handleButtonMode,
- addIconLabel,
- formUpdaterTrigger(),
- ],
- })
- export default {
- fieldType: 'radio',
- definition: radioDefinition,
- }
- export type { RadioOption } from './types.ts'
|