dental-input

0.1.3 • Public • Published

Dental Input

A Vue component that allows you to add a tooth selector input to your web applications.

Repository - CI - NPM - Demo

Installing and basic usage

npm install dental-input

Then inside your Vue component, you can import the DentalInput Vue component, as well as its default styles:

import { DentalInput } from "dental-input";
import "dental-input/style";

Then define a data ref to use for v-model:

import { ref } from "vue";

const selectedTeeth = ref(new Set);

Then in the template you can add the component:

<DentalInput 
        v-model="selectedTeeth"
        :radio-mode="false"
        style="width: min(32em, 100%)"
/>

How it works

It uses an SVG with IDs for different teeth. The teeth are a list of teeth numbered using the UNS system (tooth1 to tooth32).

<path
        id="tooth14"
        style="fill:#ffffff;stroke-width:1.25;fill-opacity:1.0"
        d="m 2840.3215,1923.7079 c -7.6354,-1.2854 ... z"
/>

Modes of operation

You can make the component behave either as a single select (radio-button) input, or a multiselect (checkbox) input. You can control this using the radio-mode property.

Filters & notations

The component provides filters that you can use to convert the tooth IDs (tooth1 to tooth32) to different notations:

https://commons.wikimedia.org/wiki/File:Comparison_of_dental_notations.svg

method name example details
uns Universal Numbering System / American System 1,2,3, ... 32 wikipedia
palmer Palmer notation / Military System 2┘,└4,2┐,┌4 wikipedia
fdi FDI World Dental Federation / ISO 3950 notation 18,19, ... 48 wikipedia
alphanum Alphanumeric notation / Letters and numbers system UR8,UR7, ... LR8 wikipedia
paleoanthropology Paleoanthropology dental notation RM³,LI¹,LI₂,RC₋ wikipedia
ada American Dental Association notation 2nd Molar,Central incisor news-medical
type Tooth type Molar, Incisor, Canine
region Tooth region Upper Right, Lower Left

In addition to the above filters, a special combinedPalmer filter can be used to show all selected teeth in a combined palmer notation:

import { filters } from "dental-input";

filters.combinedPalmer(selectedTeeth); // Example output: `12┘└42 12┐┌42`

Events

The component emits mouseover:item and mouseout:item events for each tooth.

You can, for example, keep record of the tooth under the mouse cursor by storing it in a data ref:

<script setup>
const highlightedTooth = ref(null);
</script>

<template>
    <DentalInput
            ...
            @mouseover:item="highlightedTooth = $event.target.id"
            @mouseout:item="highlightedTooth = null"
    />
</template>

Customization

Styling

The basic style control that you can directly use is using the selection-color and hover-color properties to change the colors of teeth.

<DentalInput
        ...
        selection-color="green"
        hover-color="lightgreen"
/>

You can also use teeth IDs to make any changes as desired:

@for $i from 1 through 32 {
  $tooth: "tooth#{$i}";

  ##{$tooth} {
    /* normal state props */
    
    &.selected {
      /* selected state props */
    }

    /* Show hover effect on devices that support it (non touch screens) */
    @media (hover: hover) {
      &:hover {
        /* hover state props */
      }
    }
  }
}

The provided default styles are very minimal, but you can still choose not to add them and write your own.

Changing the SVG

To use your own SVG, you can add it inside the component:

<template>
    <DentalInput
            ...
    >
        <svg .../>
    </DentalInput>
</template>

To keep your template clean, you can also import the raw SVG and use it as the v-html of a div:

<script setup>
import svg from './my.svg?raw'; // `?raw` makes Vue load the raw content.
</script>

<template>
    <DentalInput ...>
        <div v-html="svg"></div>
    </DentalInput>
</template>

The SVG must have the tooth ids defined from tooth1 to tooth32.

Note that the default styles will disable pointer events for everything else.

Other uses

This component is built in a way that there's a base generic component that allows selecting marked items in an SVG, with a tooth specific layer on top.

The base component can be extended or used as is for any other kinds of SVGs.

To do this, you can import the SvgInput component, and build on top of it:

<script setup>
import { SvgInput } from "dental-input";
import svg from './my.svg?raw';

// Set of IDs in the SVG of items that we want to turn into checkboxes / radio buttons
const itemsSet = new Set([
    'mouth',
    'nose',
    'right eye',
    'left eye',
]);
</script>

<template>
  <SvgInput :items-list="itemsSet">
    <div v-html="svg"></div>
  </SvgInput>
</template>

<style lang="scss" scoped>
div:deep(svg) {
    $itemsSet: ['mouth','nose','right eye','left eye'];

    @each $item in $itemsSet {
        ##{$item} {
            /* styles */
        }
    }

}
</style>

The source code for this component is available under Examples.

TODO

  • [ ] Rename items-list to items-set
  • [ ] Write tests
  • [ ] Add examples to the main repo
  • [ ] Alternative horizontal UI
  • [ ] Support for Deciduous teeth (baby teeth)
  • [ ] Victor Haderup notation

License

MIT

Why this project exists

I was planning to port a wxPython accounting application that I created for my father's business to the web, and couldn't find any tooth input component on the interwebz.

Special thanks

Package Sidebar

Install

npm i dental-input

Weekly Downloads

2

Version

0.1.3

License

MIT

Unpacked Size

408 kB

Total Files

6

Last publish

Collaborators

  • isword