npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dental-input

v0.1.3

Published

A tooth selector component built on top of a dynamic SVG checkbox / radio button input for Vue.js

Downloads

15

Readme

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

  • https://medium.com/travis-horn/buttons-with-custom-shapes-cabdcde7dfd1
  • https://dentagama.com/news/dental-numbering-systems
  • https://en.wikipedia.org/wiki/Dental_notation#/media/File:Comparison_of_dental_notations.svg
  • https://www.news-medical.net/health/Universal-Numbering-System-for-Teeth.aspx